CSS Vendor Prefixes

The twitterverse and style-o-sphere are abuzz with trepidation over the recent news that browser vendors will be adding support for -webkit- prefixes.

They're already past the "should we?" phase. They've moved one to "which ones?".

The current solution, apparently, is for everyone to start evangelizing "offending websites" -- ie, those websites that use -webkit- prefixes only, or are otherwise only implementing some browsers' prefixed properties, and not others'. Problem is, this really needs goes farther than just checking the prefixes; even as far as testing mobile site versions on more browsers and devices. Easier said than done, sure, but as noted in the CSSWG minutes, this is the primary concern:

tantek: Sites have webkit-specific content, and serve backup content to everyone else. Specifically for mobile content.

Florian: Regardless of how we ended up here, if we [Opera] don't support webkit prefixes, we are locking ourselves out of parts of the mobile web.

Tab: ... the discussion is about webkit being a monoculture on Mobile ...

So the problem is that many developers use only -webkit- on their mobile sites, whether due to ignorance or lack of ability to test on mobile browsers other than iOS Safari. This results in websites that "work best in WebKit", and fallback to ugly -- or at the worst, broken and unusable -- in other browsers. As PPK put it:

WebKit is the new IE6, where "WebKit" now means the iPhone. I agree. In fact, I called out this problem two years ago. Gloat moment. I. Told. You. So.

So now we're going out, bugging developers to add more prefixes to their sites -- "putting the full brunt of namespace management on web developers". Treating the symptom. The cause is that the spec is broken.

What's important to note here is that the problem is with the prefixes, and not with web developers. If standards make web developers' lives much harder, web developers ignore standards. This was true back in 1998, it's still true today.

Prefixes do make developers' lives much harder. Should I use -o-text-shadow, or does Opera (or will Opera) even support text-shadow yet? Was it -moz-border-radius-topleft or -moz-top-left-border-radius? IE had some funky syntax for gradients -- right? Yes, there are tools that can help us with this, or even do it for us, but why should we depend on tools where simple brain-knowledge ought to suffice?

The best solution I've heard of so far is to drop vendor prefixes (existing ones will have continued support) and adopt cross-vendor -alpha- and -beta- prefixes.

Web developers who want to use an experimental feature just add -beta-coolfeature to their CSS, and they're done forever - unless the feature changes (but they run that risk nowadays, too).

One opposition to this idea was voiced by Stuart Langridge:

This is wrong. We already have a solution for dealing with situations like this:

.gradient-backgrond {
    background-image: -khtml-gradient(linear, left top, left bottom, from(#fff), to(#000));
    background-image: -moz-linear-gradient(top, #fff, #000);
    background-image: -ms-linear-gradient(top, #fff, #000);
    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #000));
    background-image: -webkit-linear-gradient(top, #fff, #000);
    background-image: -o-linear-gradient(top, #fff, #000);
    background-image: linear-gradient(top, #fff, #000);
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff', endColorstr='#000', GradientType=0);

Note that there are even two syntaxes for WebKit! If the browser doesn't understand a value, it's simply ignored. If it understands multiple values (usually just two - prefixed and unprefixed), the last understood value in the list "wins". And of course some IEs don't understand any syntax, and require a separate rule that other browsers simply ignore. This is how prefixing works.

In the case of browsers implementing different syntaxes for an -alpha- feature, we would do this:

.coolness {
    -alpha-cool: 1.0; /* Opera */
    -alpha-cool: 100%; /* webkit, gecko, IE */
    -alpha-cool: 255; /* khtml (say what, now?) */
    -beta-cool: 100%;
    cool: 100%;

Yes, there are still multiple values for the -alpha- prefixed rule, but the number of values is limited by the number of ways to express a value or the number of vendors that implement the feature, whichever is fewer. The chances of the first vendor's syntax (let's say WebKit implemented the -alpha- first) working in other browsers is increased from "zero" (-webkit- vs -moz-) to "pretty good" (both use -alpha-, and will probably use the same syntax for most rules). When the -beta- comes out, it's started into the standardization process, and should have even fewer valid values. When the unprefixed version becomes the standard, there is one version that "just works", and overrides the -alpha- and -beta- implementations as it does now.

If you're worried about syntax changes in the -alpha- stage, don't be. By definition, alpha is not fit for public consumption.

Felipe G's @-vendor-unlock proposal is interesting, but still relies too much on engine namespacing. This is the same pain we went through with going from UA-sniffing to feature detection -- we should care more about what the engine can do, rather than which specific engine it is.

Better yet, we should trust the engine to know what it can do, rather than what we think we know it can do.