Vendor prefixes have failed, what’s next?

Edit: This was originally written to be posted in www-style, the mailing list for CSS development. I thought it might be a good idea to post it here as other people might be interested too. It wasn’t. Most people commenting didn’t really get the point of the article and thought I’m suggesting we should simply drop prefixes. Others think that it’s an acceptable solution for the CSS WG if CSS depends on external libraries like my own -prefix-free or LESS and SASS. I guess it was an failure of my behalf (“Know your audience”) and thus I’m disabling comments.

Discussion about prefixes was recently stirred up again by an article by Henri Sivonen, so the CSS WG started debating for the 100th time about when features should become unprefixed.

I think we need to think out of the box and come up with new strategies to solve the issues that vendor prefixes were going to fix. Vendor prefixes have failed and we can’t solve their issues by just unprefixing properties more early.

Issues

The above might seem a bold statement, so let me try to support it by recapping the serious issues we run into with vendor prefixes:

1. Unnecessary bloat

Authors need to use prefixes even when the implementations are already interoperable. As a result, they end up pointlessly duplicating the declarations, making maintenance hard and/or introducing overhead from CSS pre- and post-processors to take care of this duplication. We need to find a way to reduce this bloat to only the cases where different declarations are actually needed.

2. Spec changes still break existing content

The biggest advantage of the current situation was supposed to be that spec changes would not break existing content, but prefixes have failed to even do this. The thing is, most authors will use something if it’s available, no questions asked.  I doubt anyone that has done any real web development would disagree with that. And in most cases, they will prefer a slightly different application of a feature than none at all, so they use prefixed properties along with unprefixed. Then, when the WG makes a backwards-incompatible change, existing content breaks.

I don’t think this can really be addressed in any way except disabling the feature by default in public builds. Any kind of prefix or notation is pointless to stop this, we’ll always run into the same issue. If we disable the feature by default, almost nobody will use it since they can’t tell visitors to change their browser settings. Do we really want that? Yes, the WG will be able to make all the changes they want, but then then who will give feedback for these changes? Certainly not authors, as they will effectively have zero experience working with the feature as most of them don’t have the time to play around with features they can’t use right now.

I think we should accept that changes will break *some* existing content, and try to standardize faster, instead of having tons of features in WD limbo. However, I still think that there should be some kind of notation to denote that a feature is experimental so that at least authors know what they’re getting themselves into by using it and for browsers to be able to experiment a bit more openly. I don’t think that vendor prefixes are the right notation for this though.

3. Web development has become a popularity contest

I’ll explain this with an example: CSS animations were first supported by WebKit. People only used the -webkit- prefix with them and they were fine with it. Then Firefox also implemented them, and most authors started adding -moz- to their use cases. Usually only to the new ones, their old ones are still WebKit only. After a while, Microsoft announced CSS animations in IE10. Some authors started adding -ms- prefixes to their new websites, some others didn’t because IE10 isn’t out yet. When IE10 is out, they still won’t add it because their current use cases will be for the most part not maintained any more. Some authors don’t even add -ms- because they dislike IE. Opera will soon implement CSS animations. Who will really go back and add -o- versions? Most people will not care, because they think Opera has too little market share to warrant the extra bloat.

So browsers appear to support less features, only because authors have to take an extra step to explicitly support them. Browsers do not display pages with their full capabilities because authors were lazy, ignorant, or forgetful. This is unfair to both browser vendors and web users. We need to find a way to (optionally?) decouple implementation and browser vendor in the experimental feature notation.

Ideas

There is a real problem that vendor prefixes attempted to solve, but vendor prefixes didn’t prove out to be a good solution. I think we should start thinking outside the box and propose new ideas instead of sticking to vendor prefixes and debating their duration. I’ll list here a few of my ideas and I’m hoping others will follow suit.

1. Generic prefix (-x- or something else) and/or new @rule

A generic prefix has been proposed before, and usually the argument against it is that different vendors may have incompatible implementations. This could be addressed at a more general level, instead of having the prefix on every feature: An @-rule for addressing specific vendors. for example:

@vendor (moz,webkit,o) {
    .foo { -x-property: value; }
}

@vendor (ms) {
    .foo { -x-property: other-value; }
}

A potential downside is selector duplication, but remember: The @vendor rule would ONLY be used when implementations are actually incompatible.

Of course, there’s the potential for misuse, as authors could end up writing separate CSS for separate browsers using this new rule. However, I think we’re in a stage where most authors have realized that this is a bad idea, and if they want to do it, they can do it now anyway (for example, by using @-moz-document to target Moz and so on)

2. Supporting both prefixed and unprefixed for WD features

This delegates the decision to the author, instead of the WG and implementors. The author could choose to play it safe and use vendor prefixes or risk it in order to reduce bloat on a per-feature basis.

I guess a problem with this approach is that extra properties mean extra memory, but it’s something that many browsers already do when they start supporting a property unprefixed and don’t drop the prefixed version like they should.

Note: While this post was still in draft, I was informed that Alex Mogilevsky has suggested something very similar. Read his proposal.

3. Prefixes for versioning, not vendors

When a browser implements a property for the first time, they will use the prefix -a-. Then, when another browser implements that feature, they look at the former browser’s implementation, and if theirs is compatible, they use the same prefix. If it’s incompatible, they increment it by one, using -b- and so on.

A potential problem with this is collisions: Vendors using the same prefix not because their implementations are compatible but because they developed them almost simultaneously and didn’t know about each other’s implementation. Also, it causes trouble for the smaller vendors that might want to implement a feature first.

We need more ideas

Even if the above are not good ideas, I’m hoping that they’ll inspire others to come up with something better. I think we need more ideas about this, rather than more debates about fine-tuning the details of one bad solution.

  • http://twitter.com/ben_eb Ben Briggs

    I disagree – vendor prefixes haven’t failed at all, they have helped to spur innovation and collaboration between browser vendors. If the WebKit team had stuck solely to the specification we wouldn’t have CSS gradients, then Mozilla wouldn’t have improved the syntax. Likely without vendor prefixes, background-image:gradient(linear, 0 0, 0 100%, from(#ff0000), to (#fff)); would have been set in stone, and as we know the new syntax is vastly better.

    I would put the recent rapid development of HTML and CSS down to the freedom that prefixes have given the browser vendors. Prefixes are a good thing, overall.

  • http://andrewdupont.net Andrew Dupont

    You’ve hit on the problem: this stuff takes way too long to standardize. Solve that problem and the vendor prefix headaches disappear.

    This is why I’ve never understood why people want to get rid of vendor prefixes: it’s like wanting to get rid of the shoulders on highways because people drive on them when traffic is bad. Getting rid of them won’t fix anything, and they’re only being driven on because there aren’t enough lanes in the first place.

  • http://twitter.com/stopsatgreen Peter Gasston

    Despite the fact that the use of vendor prefixes have caused problems, I dispute the statement that they have failed. border-radius would have been broken if it had been implemented in its original state; it went through changes, and is now stable and unprefixed. Likewise, linear and radial gradients will be in their best possible state when they finally lose the prefix. The wait for a spec to move to CR before properties lose their prefix is the biggest stumbling block at the moment; transform and transition are, it seems, completely stable and ready for full implementation, and it’s this that’s causing a lot of bloat.

    As I said, there are undoubtedly problems*; but in the rush to fix them, let’s not throw the baby out with the bathwater.

    * See my blog post at http://www.broken-links.com/2011/11/15/an-argument-in-favour-of-vendor-prefixes/ to see what I think the main problems are.

    • http://twitter.com/Komputist Leif Halvard Silli

      How did the prefixes add anyting to border-radius? All they did was that they kept our attention on the fact border-radius was not standardized yet. Why do we need X number of prefixes just for that? Why can’t we use a much more simple solution – completely separated from the properties, to do that?

  • http://horia.me Horia Dragomir

    Maybe we can encourage the use of less/sass even more until the powers that be discover a better way to address this issue?

  • Adam van den Hoven

    The solution, as I see it, is not vendor prefixes (or tests for vendors either), which are the CSS equivalent of browser sniffing. 

    Instead we need a CSS-native equivalent to feature checking, Something like

    @property (background-image: url() url() linear-gradient(….)){
    }
    @selector(:last-of-type){}

    Or something, I’m not sure about the syntax. But the point is that there is some mechanism to say “I want this to return what I expect it to”. If the default behaviour is to alway say NO unless every part of everything that is passed in is comprehensible to the user agent, then it _should_ work well into the future.  it would give vendors the opportunity to introduce new features  without polluting things too much.

  • Shane Holloway

    One scheme that worked well in another context is Python’s `from __future__ import xyz_feature`.  It allowed you to optionally use new features before they were standardized within the context of the file.

    To translate the concept into CSS as a straw-man proposal, something akin to @-media queries:

        @features css-3, abc-feature, -x-experiemental-feature {
            … optional scoped block …
        }

    If the scoped block is left out, the features apply to the whole file.  We would obviously desire an inverse selection to alternatively style content when the features are not present.

    When browser implementors experiment with features, they start with a -x- namespace.  Once two or more implement the features, drop the feature prefix.  This process is akin to how extensions are adopted in the OpenGL committee.  

    The worst case for prefixes is having both a ‘-x-’ and a non-prefixed version.  Deploying a website using a ‘-x-’ prefixed versions is anticipated to break at some point in the future, but allows you to be on the bleeding edge.

  • http://leaverou.me Lea Verou

    Most of you completely missed the point. I’m not against prefixes, nor do I support them in their current form. Please read the article before posting, not just the title.

  • http://twitter.com/Komputist Leif Halvard Silli

    Your @-rules proposal goes in the right direction, IMHO. However, I would simplify it much more:  

       @experiment{div{new-property: value;}}

    The @experiment rule’s only purpose would be to hide experimental CSS from the validator. Any non-standard, un-prefixed property that is placed inside @experiment, would not cause any validaton error reprots.

    Once a CSS property gets standardized, then it would become invalid to place the property inside the  @experiment rule. This way the CSS validator would help authors keeping track of how CSS developes.
     
    JUSTIFICATION: Could @experimetn fulfill the purpose of the vendor prefixes? In my view, yes. The purposes of the vendor prefixes are:

       a) to separate standardized properties from non-standarized
        b) to draw the authors’ attention to possible differences
    between UAs w.r.t. how the prefixed properties work.

    The @experimental rule would have those effects.

    But in addition, because @experiment would make the validator not whine about use of experimental prefixes (as long as they are not prefixed – that is, then it would still whine), then    would also solve the problem that CSS validation currently isn’t very useful: Authors needs to use so many vendor prefixes etc, that it won’t validate.
     
    With regard to vendor prefixes , then they could still be used, but they would continue to be invalid and continue to trigger validation errors. But by not introducing any new prefixed properties, the vendors show good will to authors – we must assume that they would be interested in doing that, no?  

    I presented the same idea on www-archive@ (except that I suggested a more complicated selector): http://lists.w3.org/Archives/Public/www-archive/2011Nov/0017.html

  • Anonymous

    What if you think of vendor prefixes as namespace and import from them, similar to java packages. In css you would do sth. like:

    @use -webkit-box-shaodw, -moz-box-shadow, … as box-shadow;

    Usage like this:
    .selector {
      box-shadow: …;
    }

    (@use because @import is already taken)

    Could also work with versions:
    @use  -webkit-box-shadow$1.0 as box-shadow

    And import box-shadow from all “namespaces”:
    @use -*-box-shadow as box-shadow;
    (or sth similar to -*-)

    Use asterisk to import everything from a “namespace”:
    @use -webkit-*;

    And the master import rule to use everything exerpimental:
    @use -*-*;

    Thus we – developers – are aware of using experimental stuff but explicitely allow the usage.

    P.S. this disqus plugin is kickin nuts when writing the @stuff ;)

  • Anonymous

    The 3 issues you listed have never been a problem for me.

    1. Unnecessary bloat
    Tools like Sass & PrefixFree really negate the issue of duplication from the author’s point of view. There is simply no reason for anyone to hand-code 5 lines of vendor-prefixed CSS for a single property in 2011.

    From the point of view of file size, I don’t consider it bloat. If I decide I want progressively enhance the experience of the 50% of my visitors with Firefox & Chrome, 2 extra properties in my compiled CSS is a negligible price to pay.

    2. Spec changes break existing content
    This isn’t an issue if you view the use of an experimental feature as a progressive enhancement (which you totally should!)

    You will already have a solid fallback for browsers that don’t support the experimental feature – is it really a huge issue if a vendor changes the syntax & suddenly those visitors get the fallback feature? 

    I don’t consider that breaking, I consider it progressive enhancement!

    3. Web dev is a popularity contest
    Again, doesn’t matter if you view the use of experimental features as progressive enhancements. If I write some CSS that takes advantage of an experimental feature in webkit & firefox, then a year later that same feature is available with a -o- or -ms- prefix, is it an issue if I don’t use it? 

    I don’t think so. At worst, those browsers will get the feature when the unprefixed version becomes available. Progressively enhancing for a known percentage of your user base is nothing new. 

    If you’re using something like Compass or PrefixFree, you can simply keep them up to date & know that they’ll always have the latest available vendor prefixes.

  • Pingback: Some links for light reading (23/11/11) | Max Design

  • Pingback: Bruce Lawson’s personal site  : Reading List

  • Pingback: 改变web发展方向的20个HTML5网站 | Flash开发者大会

  • Pingback: 2011年回顾:改变游戏的20个HTML5网站 - 博客 - 伯乐在线

  • Pingback: 2011年回顾:改变游戏的20个HTML5网站 | 佚名工作室

  • Pingback: 20 HTML5 sites that changed the game | Armin Osmancevic

  • Pingback: Vendor prefixes: the good, the bad and the ugly

  • Pingback: 2011年回顾:改变游戏的20个HTML5网站 | 好工作博客在线

  • Pingback: Skutki dominacji WebKita ‹ GrovMan's log

  • Pingback: Vendor Prefixes: A Force For Good or Evil? - DesignModo

  • Pingback:   Vendor Prefixes: A Force For Good or Evil? by Web Factory South Africa

  • Pingback: Vendor Prefixes: A Force For Good or Evil?