Thursday, May 21, 2015

The Web No Longer Works Without WebKit

Earlier this week I wrote up the list of remaining MS prefixes. We look forward to the day we can remove each and every one of those in favor of a Standards and Interoperable alternative. No seriously, every engineer on the planet wants to build something to a design and specification that delights their customers. When a Standard lands we get a chance to do exactly that. The Standards are the blue prints and each Browser gets to build its interpretation and contribute back meaningful design changes. Once everything is done the code you write on one platform runs on all platforms. That is pretty cool and it is the promise of HTML 5.

Sometimes the standards don't move fast enough. In steps an innovator. We've all been innovators in the Browser space. Moz, Ms, WebKit and even O have all been innovators of various APIs and pre-standards. We haven't all been extremely successful with every single API proposed, but there are some APIs that stand out for sure. Probably the most successful to date has been WebKit and it's adoption on the mobile platforms. On mobile, you'll find browsers with 250+ WebKit prefixed properties and you'll find entire sites that only work in WebKit since they rely heavily on these prefixes.

WebKit is so successful in fact that to render some corners of the web a Browser has to change its shape. We have to be creative. We have to change our user agent string quite significantly to avoid detection. Then we have to model our type system after the king of the hill for the given platform. Finally we have to change internal behaviors or adapt to different input modalities in order to get reliable experiences. We do all of this so the web just works! It is a lofty goal, fun at times, confusing at others, but never boring.

So what, you might be asking, does it take to just "run the web" today if you start with a Standards browser and add a bit of WebKit to light up any broken scenarios? Well, I have a nice long list for you. So let's get started!

The First 100

EdgeHTML's First 100 WebKit APIs
To the right is our first 100 WebKit APIs for EdgeHTML. You can see that CSS was hugely impactful representing over 75 APIs. The only API layer even close to that is the FullScreen APIs and that is an area where at least Chrome has been working very hard get unprefixed versions of the APIs available. Even after they do these APIs will linger on the web for years due to their large user base. Entire sites that will only work if you have a full suite of the WebKit Fullscreen APIs available for them to use.

Many of the APIs we support are also mobile extensions. Its actually really hard to be a write once, run anywhere platform. In EdgeHTML we made a choice that we want all of your content to work seamlessly across your devices. That sometimes means implementing the mobile web APIs on the desktop and leaving desktop only APIs available on the mobile web. This is simply a price that we pay to achieve a unified platform. We'll have to see how this plays out because I also suspect we'll see cases where our desktop or mobile browser breaks when confronted with certain browser detection logic.

As an example, a few weeks back I brought up an issue around window.platform returning Win64 since we are a 64-bit browser. Chrome, it seems, returns Win32, even if they are running in 64-bit mode. Recently we found a site that was detecting precisely "Win32" and if you weren't that then you must be something else, in this case a phone. You can imagine how absurd that site looked on my 4k monitor.

CSS FlexBox

Multiple FlexBox Versions
So let's talk about FlexBox. You might have thought, 18 APIs is CRAZY, why would there be so many. You'll notice that there are two different implementations hidden in there. One is for mobile Safari and the other is for the current Chrome desktop browser.

We also had the ms prefixed version and the standards version of all the same APIs. While we could do some internal management to share some code, each one has its own little quirks to implement.

If I could pick a single feature that convinced me vendor prefixes hurt the web more than it helps, then it would be FlexBox. Probably only because of the many vendor prefixed iterations and how much of a staggered pickup there was in the web. Along with the fact that the mobile web picked the webkit prefixed versions AS their standard versions at some point along the way and often lacked fallback to anything close to a standards API.

CSS Core

Some Sharks Were Jumped Implementing CSS Core
This is my favorite grouping of properties, but you'll also get my pitch on why FullScreen is a close second in a minute.

What you'll notice is only a small portion of these APIs are actually in ANY BROWSER that we know of other than EdgeHTML. In fact 5 of the 23 are in other browsers. The other 18 are unfortunately aliases we picked up to actually fix sites that were broken. Why were they broken? Because they took another API and appended webkit to it and expected it to work. And sometimes it did.

Okay, that's not the whole story. We also, for various technical reasons, had to implement some webkit properties as aliases of our own standards versions. Due to technical limitations this meant adding WebKit when there wasn't any. If you look at all of the Background and Border properties they all really map to our existing standards versions of those APIs and to make our plumbing work, we had to implement each longhand fully. Unfortunate, but true.

Many of these are now on our clean-up lists and may not survive until the day we ship. I can in all transparency share this with you now because you could find all of this information yourself by simply walking our type system. Nothing to hide here ;-)

Update: All EdgeHTML only webkitBackground* and webkitBorder* style properties have indeed been removed. All other properties are available on at least 1 WebKit platform, whether it be Mac, iOS Phone or iOS Tablet.

FullScreen

The data for fullscreen requires that I print out the data on platform differences. IE supports all of the shown methods and properties while Chrome and Safari only support those that have a 1 in their column.

Wildly Varying WebKit Support for FullScreen Aliases

So, I really, really like this one because of the case-sensitive S in screen differences. Yes, we had to implement two APIs, but so do all the other guys so it is okay. You can also see that we have varying support for different events between the WebKit browsers and that there are some older Safari only APIs (maybe mobile only, but I think it is Safari only) where Chrome either never had them or recently removed them. I actually do apologize that I don't have my normal historical data. Maybe someone can share with me and I can back fill in more details. Or perhaps a site like icanuse might already have it and I just have to go dig it up.

The above set of full screen APIs did not come cheap for us. It came through many different bug fixes and often as a surprise. We never thought there would be APIs that varied only by the case of a single letter. That isn't normally something you search for. Had my PMs done so, they probably would have used a pivot table anyway and those things group case-insensitively and so the APIs would have been lost until we got the bugs ;-)

Table Stakes

Odds and Ends that Make a Huge Difference
This is the last set I'll go into details on before I provide you guys with a nice grouped up final listing of the full 100.

The first group I've named only Browser Detection. That isn't what the APIs were intended for, but when we discovered them on the web, that is primarily how they were being used. The presence of these APIs was almost always to figure out if a Browser was using the "WebKit Rendering Engine". I tried to do a web search for it today and found that OUR MSDN DOCUMENTATION is the first hit. I don't know how to think about that really, but it likely means the time left on this API is short as even the WebKit documentation for it is slim. Chrome already removed it and so it just lingers to support a few mobile sites that can likely now only be viewed using an iPhone or a Windows 10 Phone.

The next group are the purely mobile extensions. They only tend to show up in browsers when running on phones.

Properties like webkitTapHighlightColor are generally useful though and are starting to show up on more desktop platforms, probably due to the prevalence of touch hardware on laptops and tablets. The webkitTextSizeAdjust property is truly only meant for a phone. It helps to control text scaling on high DPI screens and allows the page author control over whether or not the browser is allowed to automatically scale things up and to what extent and tolerances. This is yet generally useful, but in EdgeHTML we'll support it even on the desktop as a property. You can get and set it. You can query your computed style for it. We won't, however, apply any of the scaling logic unless you are using the tools to put yourself into phone emulation mode. Having properties like these generally available is very useful since you can quickly switch between device modes, without reloading your page, to see how things will look.

Wrap-Up

My excitement about getting rid of the MS prefixes was about getting rid of legacy and removing things that would result in a website only working in IE or EdgeHTML. That isn't the web I'm interested in. My excitement about this post is actually much greater. It shows that a major Browser vendor can take on a challenging task to make the web just work and steer towards both Standards and Interoperability in the process. While our hope is always that these webkit properties will slowly be timed out with use counters, we might realistically be looking at a few years. In the meantime, we can hopefully enjoy a web that works better on any Browser and on any device.

Full List
Apologies for not making it a pivot table, but as noted above, Excel likes to group like named entities together into an aggregate and I wanted to show everything broken out. Enjoy!

Entity Category Chrome 42 Safari IE Only
WebKitPoint Browser Detection 0 1 0
webkitConvertPointFromNodeToPage Browser Detection 0 0 1
webkitConvertPointFromPageToNode Browser Detection 0 0 1
webkitAnimation CSS Animations 1 1 0
webkitAnimationDelay CSS Animations 1 1 0
webkitAnimationDirection CSS Animations 1 1 0
webkitAnimationDuration CSS Animations 1 1 0
webkitAnimationFillMode CSS Animations 1 1 0
webkitAnimationIterationCount CSS Animations 1 1 0
webkitAnimationName CSS Animations 1 1 0
webkitAnimationPlayState CSS Animations 1 1 0
webkitAnimationTimingFunction CSS Animations 1 1 0
webkitBackground CSS Core 0 0 1
webkitBackgroundAttachment CSS Core 0 0 1
webkitBackgroundClip CSS Core 1 1 0
webkitBackgroundColor CSS Core 0 0 1
webkitBackgroundImage CSS Core 0 0 1
webkitBackgroundOrigin CSS Core 1 1 0
webkitBackgroundPosition CSS Core 0 0 1
webkitBackgroundPositionX CSS Core 0 0 1
webkitBackgroundPositionY CSS Core 0 0 1
webkitBackgroundRepeat CSS Core 0 0 1
webkitBackgroundSize CSS Core 1 1 0
webkitBorderBottomLeftRadius CSS Core 0 0 1
webkitBorderBottomRightRadius CSS Core 0 0 1
webkitBorderImage CSS Core 1 1 0
webkitBorderImageOutset CSS Core 0 0 1
webkitBorderImageRepeat CSS Core 0 0 1
webkitBorderImageSlice CSS Core 0 0 1
webkitBorderImageSource CSS Core 0 0 1
webkitBorderImageWidth CSS Core 0 0 1
webkitBorderRadius CSS Core 1 1 0
webkitBorderTopLeftRadius CSS Core 0 0 1
webkitBorderTopRightRadius CSS Core 0 0 1
webkitBoxSizing CSS Core 0 0 1
webkitFilter CSS Filters 1 1 0
webkitAlignContent CSS FlexBox 0 1 0
webkitAlignItems CSS FlexBox 0 1 0
webkitAlignSelf CSS FlexBox 0 1 0
webkitBoxAlign CSS FlexBox 1 1 0
webkitBoxDirection CSS FlexBox 1 1 0
webkitBoxFlex CSS FlexBox 1 1 0
webkitBoxOrdinalGroup CSS FlexBox 1 1 0
webkitBoxOrient CSS FlexBox 1 1 0
webkitBoxPack CSS FlexBox 1 1 0
webkitFlex CSS FlexBox 0 1 0
webkitFlexBasis CSS FlexBox 0 1 0
webkitFlexDirection CSS FlexBox 0 1 0
webkitFlexFlow CSS FlexBox 0 1 0
webkitFlexGrow CSS FlexBox 0 1 0
webkitFlexShrink CSS FlexBox 0 1 0
webkitFlexWrap CSS FlexBox 0 1 0
webkitJustifyContent CSS FlexBox 0 1 0
webkitOrder CSS FlexBox 0 1 0
webkitAppearance CSS Intrinsic Control Styling 1 1 0
webkitColumnBreakAfter CSS MultiColumn 1 1 0
webkitColumnBreakBefore CSS MultiColumn 1 1 0
webkitColumnBreakInside CSS MultiColumn 1 1 0
webkitColumnCount CSS MultiColumn 1 1 0
webkitColumnGap CSS MultiColumn 1 1 0
webkitColumnRule CSS MultiColumn 1 1 0
webkitColumnRuleColor CSS MultiColumn 1 1 0
webkitColumnRuleStyle CSS MultiColumn 1 1 0
webkitColumnRuleWidth CSS MultiColumn 1 1 0
webkitColumnSpan CSS MultiColumn 1 1 0
webkitColumnWidth CSS MultiColumn 1 1 0
webkitColumns CSS MultiColumn 1 1 0
webkitTextFillColor CSS Text Masking 1 1 0
WebKitCSSMatrix CSS Transforms 1 1 0
webkitBackfaceVisibility CSS Transforms 1 1 0
webkitPerspective CSS Transforms 1 1 0
webkitPerspectiveOrigin CSS Transforms 1 1 0
webkitTransform CSS Transforms 1 1 0
webkitTransformOrigin CSS Transforms 1 1 0
webkitTransformStyle CSS Transforms 1 1 0
webkitTransition CSS Transitions 1 1 0
webkitTransitionDelay CSS Transitions 1 1 0
webkitTransitionDuration CSS Transitions 1 1 0
webkitTransitionProperty CSS Transitions 1 1 0
webkitTransitionTimingFunction CSS Transitions 1 1 0
webkitWritingMode CSS Writing Modes 1 1 0
onwebkitfullscreenchange FullScreen 1 0 0
onwebkitfullscreenerror FullScreen 1 0 0
webkitCancelFullScreen FullScreen 1 1 0
webkitCurrentFullScreenElement FullScreen 1 1 0
webkitDisplayingFullscreen FullScreen 0 1 0
webkitEnterFullScreen FullScreen 1 1 0
webkitEnterFullscreen FullScreen 1 1 0
webkitExitFullScreen FullScreen 1 1 0
webkitExitFullscreen FullScreen 1 1 0
webkitFullscreenElement FullScreen 1 1 0
webkitFullscreenEnabled FullScreen 1 1 0
webkitIsFullScreen FullScreen 1 1 0
webkitRequestFullScreen FullScreen 1 1 0
webkitRequestFullscreen FullScreen 1 1 0
webkitSupportsFullscreen FullScreen 0 1 0
webkitTapHighlightColor Mobile Extensions 1 0 0
webkitTextSizeAdjust Mobile Extensions 0 0 1
webkitMatchesSelector Selectors API 1 1 0
webkitUserSelect Text Selection 1 1 0

No comments:

Post a Comment