Prefix or Posthack
Issue № 309

Prefix or Posthack

As CSS browser support increases, including impressive strides by the IE9 team, more and more authors are plunging into CSS3. As they do so, they’re facing vendor prefixes—the -*- properties like -moz-border-radius, -webkit-animation, and so on.

Article Continues Below

Perhaps inevitably, there’s been some grumbling about these prefixes. There have been calls to drop them, or to collapse all the vendor-specific prefixes into a single prefix like -beta-. The primary pushback is that nobody really wants to write the same thing four or five times in a row just to get, say, rounded corners on an element.

While such grousing is understandable, it is exactly the inverse of what should be happening. We ought to praise vendors for using prefixes, and indeed encourage them to continue. Beyond that, I hold that prefixes should become a central part of the CSS standardization process. I do this not for the love of repetition, but out of a desire to see CSS evolve consistently. I believe that prefixes can actually accelerate the advancement and refinement of CSS.

Look back in horror#section2

To understand why we have vendor prefixes at all, it’s instructive to look back at the box model, which almost killed CSS before the turn of the millennium. Inconsistent box model implementations created a crisis. To escape the danger, we had to build an entirely new behavior on top of a markup feature and invent a whole class of hacks.

For the young whippersnappers in the audience who missed all the fun, what happened was this: In the first round of browsers that supported CSS, Netscape implemented the box model found in the CSS specification. That meant that width and height referred to the width and height of the content area. But Internet Explorer implemented the intuitive box model, which meant that width and height declared the dimensions of the box’s outer border edge.

Whichever of the two you think better, the fact remained that there were two major browsers with large user bases that were completely incompatible with each other. It was the late 1990s, we were fighting like hell to leave behind the morass of “this site best viewed in…” badges, and here we had a situation where a layout that worked fine in one browser could completely fall apart in another.

Compounding the problem was that neither browser could change its behavior to mirror the other. Assume for a moment that the IE team decided to change their CSS support to reflect the specification. To do so would mean that tens, even hundreds of thousands of sites that worked in IE would break—would quite literally fall apart, visually speaking—in the “fixed” version. While the standards community would have applauded the move, the rest of the world would have written off the browser as unusable. And even if the Working Group decided to change the specification to match IE’s behavior, Netscape would then have faced exactly the same problem.

Thus DOCTYPE switching was created. The entire regime of “standards mode” and “quirks mode” was born of this problem. The solutions to other problems were rolled into DOCTYPE switching, but the box model triggered it. Think about it: because two vendors did things differently, browsers now have to maintain two different primary rendering models and choose which to use based on an SGML declaration that says nothing about rendering.

Furthermore, the first wave of CSS hacks were devised to address exactly the same problem. The classic example of the genre gives it away in the title: The Box Model Hack. In fact, the hack itself was based on flaws in syntactical parsing of voice-family values, but nobody ever called it “the voice-family hack.”

The funny part is that this wasn’t the only instance where a box model inconsistency led to trouble. Not long after DOCTYPE switching saved CSS, the Explorer team implemented some features of CSS positioning. One of the properties they implemented was clip. Having learned their lesson with the box model brouhaha, the engineers at Microsoft paid very close attention to the specification and did what it said.

Shortly after they shipped it publicly, the CSS Working Group massively changed the way clip worked. The syntax looked exactly the same, but yielded very different results.

Once more, the specification clashed with the behavior of a publicly available browser (or, if you prefer, vice versa). The eventual resolution was to revert to the earlier behavior and drop the new behavior entirely. That renders clip effectively useless on any element with unpredictable height and width—which is to say, any normal-flow, non-replaced element such as a div or a paragraph. Although other solutions were proposed, they never came to pass, and clip withered away.

Imagine a different outcome#section3

Suppose that instead of implementing clip, the IE team had implemented -ms-clip. In that case, a behavior change in a later specification wouldn’t have been so difficult to overcome. Because a vendor prefix marks a property as “in progress,” it’s much easier for a vendor to go back and change it. Thus the IE team could have changed the way -ms-clip worked in their next release, explaining to developers that they were updating their experimental implementation to match changes to the specification.

Even if they had decided that that was impossible to do, the damage of the “bad” implementation would have been quarantined in the prefixed version of the property. Other vendors could have implemented the new version of clip (using their own prefixes), unaffected by what the IE team had done. A single vendor could not pin the specification and other vendors in place by their actions.

This is the promise that prefixes provide: A way to mark properties as “in progress,” and so not necessarily guaranteed to always act the same in future releases; an out for vendors who need to make those changes; and a defense against bad or premature implementations that happen to ship first. They add sorely needed flexibility to the advancement of CSS.

Of course, we could just say: “When a browser is wrong according to the specification, then they have to change even if it breaks the layout of web sites.” With prefixes, that’s a lot easier to accomplish, thanks to the warning that prefixes embody. Without prefixes, it’s very difficult or even impossible. Microsoft never did change the way it handled width and height in legacy pages—instead, it used DOCTYPE switching to behave differently on new (theoretically more “standards compliant”) pages. It was a useful and necessary trick, but that kind of trick only works once.

Even now we suffer#section4

Lest you think that all this silliness is an artifact of history, here are two cases of inconsistency happening right now:

  • Mozilla and WebKit browsers render box-shadow blurring very differently, and neither fully conforms to the specification. As I write this paragraph, a lengthy and heated debate is raging on the www-style mailing list. At least one, and possibly both, implementations will have to change the way they handle shadow blurring to achieve interoperability. The same holds true for any Microsoft or Opera implementations.

  • Mozilla and WebKit browsers both support gradients, but they use radically different syntaxes to achieve the same basic result. Now imagine a world where the vendors had implemented gradients without the prefixes. You would have three choices:

    1. Pick which browser gets a gradient and which one doesn’t.
    2. Use CSS hacks or browser sniffing to serve up different styles to different browsers.
    3. Walk away from using gradients entirely.

    And there are three choices here only because the gradients use wildly different value syntaxes, thus opening the door to option number one. In a case where two implementations use the same value syntax but have very different effects—as was true with clip—then there are really only the last two options: hack and sniff to send totally different styles, or just walk away.

We’ve seen this movie played out many times over the history of CSS.  There’s no reason to want to see it again. It was bad enough the first dozen times.

Prefix or posthack#section5

But are prefixes really any better?  After all, it’s been said that vendor prefixes are the new CSS hacks. As Aaron Gustafson pointed out in a recent article, this:

-moz-border-radius: 10px 5px;
-webkit-border-top-left-radius: 10px;
-webkit-border-top-right-radius: 5px;
-webkit-border-bottom-right-radius: 10px;
-webkit-border-bottom-left-radius: 5px;
 border-radius: 10px 5px;

…is reminiscent of this:

padding: 10px;
width: 200px;
w\idth: 180px;
height: 200px;
heigh\t: 180px;

In terms of repetition and annoyance, yes, the two are very much alike. But they’re fundamentally different in this way: Prefixes give us control of our hacking destiny. In the past, we had to invent a bunch of parser exploits just to get inconsistent implementations to act the same once we found out they were inconsistent. It was a wholly reactive approach. Prefixes are a proactive approach.

Furthermore, prefixes are a temporary hack. As time goes on and implementations become consistent, browsers will drop the prefixes. From then on, authors will be able to write one line for border-radius instead of six-plus lines of CSS. Without them, we’re just waiting for the next botched implementation that forces us to support it through hacks for years upon years.

That’s why creating a unified prefix, such as -beta- or -w3c-, is at least half a step backwards. It would preserve vendors’ ability to mark properties as “in progress” and make changes as needed. Unfortunately, it would completely rob authors of the ability to excise, or even feed a different value to, one particular browser if it has a botched implementation. From an author’s point of view, a unified prefix is no better than a world without prefixes.

I sometimes feel the same way about pre-processor methods to handle prefixes, whether on the server side (using tools like Less) or client side (any number of JS frameworks). When using these tools, it’s possible to just write border-radius declarations and have the tool expand that into the requisite list of prefixed declarations. On the one hand, they’re a very useful way to reduce typing and keep the authoring neat and clean. On the other, they’re just like a unified-prefixed or unprefixed world: one bad browser implementation away from breaking pages.

The advantage is that if something goes haywire, any author can go back, disable the pre-processor, and write out the prefixes by hand. Alternatively, the pre-processor can be updated to handle the problem. Either way it’s a little more cognitive overhead for the author, but not too much.

The downside is more philosophical, but it’s no less important for that: By hiding the prefixed properties behind a processor, authors may forget that what they’re using is experimental and subject to change.  Cognitively, they may start to treat what they’re using as settled and stable when it may be nothing of the kind.

Make prefixes really matter#section6

I believe so firmly that vendor prefixes are a good thing that I’m prepared to take the next logical step: Vendor prefixes should be made more central to the standards process. They should be required of newly implemented properties and should be the mechanism by which interoperability is declared.

Here’s what I mean: Suppose someone invents a new property called text-curl. Immediately, three vendors implement it. Each of them should be required to add a vendor prefix to their implementation. Thus, we’d see things like this:

h1 {
 -webkit-text-curl: minor;
 -moz-text-curl: minor;
 -o-text-curl: minor;
 text-curl: minor;
 }

Over time, the vendors refine their implementations in response to bug reports and clarifications by the Working Group. Eventually, the Working Group decides that two of the three are fully interoperable. Those implementations then get to support the bare text-curl. The third does not.

At that point, authors might decide to simplify their styles like so:

h1 {
 -webkit-text-curl: minor;
 text-curl: minor;
 }

Instead of hacks proliferating over time, they’re peeling away. Eventually, we’ll only need a single text-curl line.

So what happens when a new implementation debuts? It uses the prefix in its first release, no matter how many interoperable implementations already exist. That might mean that we’d have to go back and change the CSS to say:

h1 {
 -ms-text-curl: minor;
 text-curl: minor;
 }

Then, as soon as the Working Group deems the implementation of -ms-text-curl interoperable, the prefix can be dropped in the next release of IE. At that point the CSS can be reduced to a single, unprefixed line. Again, the number of hacks dwindles over time.

Of course, each of those vendors will continue to support the prefixed properties, so even if we don’t prune the prefixed lines, each supporting browser will recognize the unprefixed property and use it (since it comes after the prefixed declaration). For any browser that implements a prefixed version that doesn’t manage to get to an unprefixed state, its own prefixed property will still work. Even if the CSS is never touched again, it will continue to function.

Having said that, return for a moment to the time when the Working Group said that two implementations were interoperable and could thus drop the prefixes. That serves two purposes. First, as I said before, it marks a property as having enough interoperability to allow progress in the standards process.

But the other thing it does—and this is arguably more important—is force the vendors and the Working Group to work together to devise the tests necessary to determine interoperability. Those tests can then guide those who follow, helping them to achieve interoperable status much faster. They could literally ship the prefixed implementation in one public beta and drop the prefix in the next.

This reverses the way things are done now. As it stands, the process is set up so that when any CSS module reaches the Candidate Recommendation stage, vendors can drop the prefixes from properties in that module. But that just opens us up to the possibility of another botched implementation and a future of hacks to work around the error.

As proposed here, a module would be permitted to reach Candidate Recommendation once all of its properties had at least two unprefixed implementations in the wild. Any implementations that came after would start prefixed and drop the prefix once they had proven, in the wild, that their prefixed implementation matched the existing unprefixed implementations. Instead of being a minor gamble, unprefixed properties would come as close to a guarantee as anything we’ve seen to date.

Conclusion#section7

If the history of web standards has shown us anything, it’s that hacks will be necessary. By front-loading the hacks using vendor prefixes and enshrining them in the standards process, we can actually fix some of the potential problems with the process and possibly accelerate CSS development.

So the next time you find yourself grumbling about declaring the same thing four times, once for each browser, remember that the pain is temporary. It’s a little like a vaccine—the shot hurts now, true, but it’s really not that bad in comparison to the disease it prevents. And in this case, you’re being vaccinated against a bad case of multi-year parser hacking and browser sniffing. We suffered through that long plague once already. Prefixes will, if used properly, ward off another outbreak for a long time to come.

58 Reader Comments

  1. The solution seems simple, there are 3 kinds of properties in CSS:

    1. Proposed (not present in any staandard)
    2. Draft (in a draft standard)
    3. Recommended (in a recommended standard)

    Correspondingly, there should be 3 levels of support:

    1. Implementation to vendor proposal (e.g. -moz-border-radius)
    2. Implementation to draft standard (e.g. -beta-border-radius)
    3. Implementation to recommended standard (e.g. border-radius)

    Vendor prefixes already exist, and they’re as brittle as the article explains – and it’s right that they should be. Anyone who uses them knows they’re playing to the vendor’s whim. However, once there is agreement on how a particular property should work, this (draft) functionality should be made available in a consistent way.

    The easiest way (in my opinion) is to agree on a reserved vendor prefix, -beta- or -draft-, and then each vendor can either map this to their vendor implementation (if it matches) or to a new implementation (which they would have to implement in any case, at least before the standard was agreed).

    Of course, a -beta- prefixed property may still change its behaviour if the draft spec is revised, but then by using a -beta- prefix in your CSS you would understand that.

  2. Excuse the -formatting-, the preview window didn’t show my – hyphen-surrounded-text – with the strikethrough

  3. Great explanation of why -beta- prefix would be a step backward. I love your idea regarding the vendors being required to add a prefix for any new implementation, thus giving them time to work out bugs and get real feedback from developers and the Working Group.

    Something I’ve been wondering, though, is should we always include the non-prefix version for future-proofing? Since we can’t predict whose implementation will become standardized couldn’t this lead to undesired results in the future?

  4. Even big names in our industry questions the value of prefixes. “I wrote a piece”:http://itpastorn.blogspot.com/2010/03/ppk-is-wrong-vendor-prefixes-are.html about this in March, but Eric Meyer says it so much better than I could.

    I am also very glad to see that Eric addresses the fact that vendor prefixes never should be the last rules. Something that most authors seem to get wrong. (Incidentally, “I’ve written about this as well”:http://itpastorn.blogspot.com/2009/06/do-not-put-experimental-features-last.html)

  5. If you’re ending up using vendor prefixes for rounded corners more than once in your CSS, then you’re probably doing something wrong.

    Just create a class for rounded corners and apply it in your HTML document. ie:

    .rc{
    -webkit-border-radius: 5px;
    -khtml-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
    }

    This approach will let you modify all the rounded corners in your site in one place. Also using .rc in your markup will let you modify all the rounded cornered elements w/ JavaScript (for older browsers).

  6. @gercheq
    Wrong. More CSS is better than more markup. Reduces traffic and keeps presentational stuff out of your HTML.

    @Topic
    I’ve not read the entire article yet but this seems to be the first really absurd proposal to be published on ALA. More browser specific code and proprietary stuff? You must be kidding, Eric!

  7. I’m a programmer who has to do CSS on occasion. I find that using meta-languages like SASS or Less make handling this ‘prefix explosion’ a lot easier.

    I’ve created mixins for CSS3 functions where I only need to pass in a single line of code, e.g. +border_radius( 10px ), and the mixin handles all the browser-specific code necessary for that functionality. If anything should ever change, I change it once and all the rules change automatically.

    This may be to “programmery”. I work with 4 designers and none of them are interested in learning meta-languages, even though for me, it cuts down on code-duplication, errors immensely.

    http://sass-lang.com/

  8. Thanks for this post Eric, I was a little perplexed by Aaron’s article referring to the vendor prefixes as hacks and I think your article has more than rectified the confusion surrounding the use of them. Bruce Lawson also explains their use http://bit.ly/c1lMbu on his personal site.
    @Florian – It is not absurd, if you read the article it explains it sublimely.

  9. ryanswedal, I would say that in any case where the value syntaxes of all the vendor-prefixed properties yield the same results, add the unprefixed version at the end of the list. In a case where I have to write different values for different prefixed versions to get a consistent result but I was determined to use them anyway, I’d probably leave off the unprefixed property at the end because the inconsistencies in the prefixed properties means there’s a higher-than-usual chance of the specification having to change.

    I absolutely recommend listing the unprefixed property last whenever you have it, of course. That leverages the cascade to future-proof your CSS as best you can.

  10. kyangareth, as I explained in the article, I disagree that @-beta-@ (or @-w3c-@ or any other unified prefix) is a good idea. From an author’s point of view, it’s literally no better than not having any prefixes at all. From an implementor’s point of view it’s a little better than no prefixes, but not much; it becomes more difficult to quarantine the ill effects of a bad implementation.

  11. I understand all the points that has been made so far. Overall, it seem like we all are willing to suffer with a little pain now for a better solution in the future. However, how long does a vendor property exists?

    I see the problem not so much as using the prefixes but how long the prefixes linger until the property gets the blessing of the CSS group (no blame, no flame here guys). If I remember, border-radius has been around for a while (two years?) and with nearly every browser supporting now (IE9 cannot come soon enough).

  12. Thanks for the thoughtful article. Writing a few lines of extra code for an in-progress feature seems a small price to pay if it helps browser vendors continue making progress. Also, the thought of using Javascript to handle CSS vendor prefixes makes my skin crawl, so I’m glad to read this perspective on the issue.

  13. I agree with everything Eric has said but I can’t help feeling that it just more lines of CSS. It’s also more work to keep up with which browser supports what and how.

    It’s an interesting topic and I look forward to what will happen in the future.

  14. I’m confused by your closing proposal that new implementations be required to use ONLY prefix codes until compliance is certified.

    It seems to me that this has an absolutely chilling effect on new browsers and other tools. First, they can’t actually render existing CSS until their compliance is certified. Worse, the organizations that would issue the certification might well have an interest in delaying or denying that certification, since every week of delay gives them more time for their advertising campaign “We have text-curl, and CoolNew doesn’t!” So, if we really enforce this, we’ll never have a new browser.

    One thing that might easy the burden: use pre-processors in the opposite direction. For example, right now I habitually write

    -moz-border-radius: …
    -webkit-border-radius: …
    -border-radius: …

    A preprocessor could generate the vendor prefixes automatically *unless* you supplied an alternative. So, in the normal case you’d get a pile of identical vendor prefixes, and in the exceptional case you could specify the “usual” behavior and a special “mozilla” behavior, and have the webkit prefix alone generated by the preprocessor.

  15. Pre-fixes as they are now have worked very well, border-radius being the obvious success. But do we really want some sort of W3C certification of every property that every browser implements?

  16. I very much like your proposal, although the CSS working group would certainly need the vendors to dedicate some substantial additional time to handle all that extra browser testing. Hopefully the major vendors will step up to the plate and do this.

    Eric mentioned a couple different reasons why one might pause before considering pre-processors (to expand a single declaration of an experimental property into the appropriate format for various vendor implementations). The first concern, as I read it, is that you’re relying on an additional tool in the chain that could fail you or need maintenance as implementations change, and authors need to be savvy enough to realize when the _browser_ is failing them versus when the _pre-processor_ is falling down on the job. This seems to me like the entire point of using a pre-processor: it’s an additional piece of code, yes, but one that enables you to handle all the different vendors’ varying behaviors in a single place. As such, it’s certainly overkill for smaller projects, but possibly helpful for larger company-wide systems.

    The second concern, the philosophical concern with pre-processors, is that they might lull us into thinking the properties are more stable than they really are — after all, there no longer needs to be any difference between the experimental properties and the tried-and-tested ones when writing our own CSS. I’m wondering why we don’t think of the pre-processors as producing their own experimental implementations and write the code appropriately. In that case, authors would write their CSS using _the pre-processor’s vendor prefix_ for the experimental properties it needs to handle, and the pre-processor would implement the property by converting the syntax it supports to the syntaxes supported by the various experimental implementations (and avoiding buggy or quirky vendor implementations as appropriate).

    Not sure why I ended up thinking so much about the pre-processor issue, since I’m not convinced they make sense on most of my projects anyway… but there you are.

  17. bq. Worse, the organizations that would issue the certification might well have an interest in delaying or denying that certification, since every week of delay gives them more time for their advertising campaign “We have text-curl, and CoolNew doesn’t!”

    Once the properties are standardized with two interoperable implementations, I don’t see any reason why the certification necessarily needs to require much direct assent from the actual humans on the CSS working group. Other than the initial engineering challenges with developing an appropriate test framework, why can’t we simply require that the initial implementations demonstrate their interoperability with a comprehensive automated test suite reviewed by the full CSS Working Group? Then, any implementation that passes the agreed-upon test suite can drop the vendor prefix, provided that a brief peer review period (in the form of a publicly-distributed build that is publicly documented to implement the properties in question) doesn’t reveal shortcomings in the test suite.

    This may not guarantee that long-established vendors can’t hassle new vendors at all, but coupled with the diversity of vendors on the Working Group and the likelihood that any serious new vendor would themselves join the Working Group, I think it would likely prevent major problems.

  18. A very nice, well-reasoned article. But I do have an issue with the proposal to require browser makers to first ship their implementations of a new CSS feature with their prefix AFTER the standard has be formalized and recommended. As we all know, browser adoption rates lag significantly in some sectors of the world. This has the potential of requiring web developers to support a prefixed CSS feature to target a specific browser for a long, long time. Once the standard is tested and recommended, browser makers should be required to support that feature as recommend. If they botch the implemtation of a recommended standard, that becomes their nightmare not that of millions of web developers.

    If a browser maker is being a good, proactive citizen and testing the implementation of a new CSS feature, then by all means, require the use of a prefix. Once the spec for a new feature is well-tested and implemented by two browsers, don’t require more prefixes by latecomers.

    Additionally, when a browser is in development mode and a preview release is available, prefixes for new CSS features would be good.

  19. Adding -@beta@ prefixes is, as you said, a bad idea.

    But writing a CSS rule four different ways is also a bad idea, no matter how you spin it.

    In other branches of technology, when the problem of supporting multiple platforms with different implementations arises, the solution is to create an abstraction layer. This what the Java Virtual Machine does, and what Less and SASS try to do.

    I don’t use Less or SASS*, but they seem like the _correct_ solution to this problem. Maybe I’m idealistic, but I don’t think designers should be the ones worrying about browser implementation details. That’s the whole point behind standardization. It’s what allows Java developers to write high-level code without worrying about how each platform converts it to machine code.

    It’s a waste of time, energy and money for those of us with actual clients & deadlines to memorize four different syntaxes for creating gradients; but unforunately it’s what we have to do. It would be very cool to see more discussion around tools for abstracting vendor-specific CSS syntaxes.

    Abstraction for the pragmatists, vendor-prefixes for the purists.

    _* For some reason I find the particular implementations of Less and SASS unappealing, though I’m not sure what; perhaps the foreign syntax. However, I think they have the right idea in general._

  20. Great article. Way too many people (including web developers) see vendor prefixes as some kind of anachronistic evil, forcing proprietary solutions on us and slowing down standards development…when (in most cases) they are doing just the opposite!

    If working implementations didn’t exist before a feature was standardized many of them would be the lesser for it, but if we were then tied to working around early (buggy/less-than-optimal/whatever) implementations through CSS hacks or javascript, it would be…very unfortunate.

    I do have an issue with your proposal, though, Eric. I am not an expert on the CSS working group process by any means, but AFAIK
    1) the working group can’t “certify” browsers in any sense, they can only certify a specification. Luckily all the major browser vendors have bought into the process and actively participate.
    2) Working and compatible implementations are already required for specs to advance to Proposed Recommendations.
    3) *Extensive* test suites are also required for the same (see http://www.w3.org/Style/CSS/Test/ )

    Things haven’t always been this way, and some of these changes have been made relatively recently, causing things like CSS2.1 still being technically finished even as CSS3 is rolling through (we can thank the new modular spec approach for that).

    Just wanted to point that out. Again, great (and very welcome) article!

  21. The vendor prefix is one of those insanely simple yet ingenious devices that does indeed make the difference between CSS that can “evolve consistently’ and one that’s stuck in the mud.
    It works.
    I’ve been puzzled by suggestions that it be simplified.
    The bit of repetition involved is a small price to pay to keep things moving forward while at the same time maintaining a level playing field for implementors.

  22. bq. Maybe I’m idealistic, but I don’t think designers should be the ones worrying about browser implementation details. That’s the whole point behind standardization. It’s what allows Java developers to write high-level code without worrying about how each platform converts it to machine code.

    But that’s exactly the point…these features are still being standardized. When they are standardized, no vendor prefixes will be necessary.

    It only seems so bad because features that obviously should have been standardized a decade ago are only now being added, which — with browsers being iterated so frequently and so much extra attention being paid to the process — is a situation we hopefully won’t find ourselves in again.

    “-*-box-shadow” is a great example. The borders and background module should be moved to a proposed recommendation soon enough (it’s in last call right now), and browsers implementing the feature after that can all just call it “box-shadow”, without a prefix. someday in the distant future all the current browsers with the prefixes will disappear, and only the standard will appear in our stylesheets. Until then, yes, there are multiple entries or tools like SASS and LESS for us to use, to ensure interoperability with what were by definition non-standard implementations.

  23. “SASS”:http://sass-lang.com/ and “LESS”:http://lesscss.org/ are well suited to solving the problem of having to deal with vendor prefixes. One of the many barriers to entry with SASS in particular has been the indentation aware syntax; developers/designers who work with CSS seem to really like semi-colons and curly braces (no idead why).

    If you haven’t checked out “SCSS”:http://nex-3.com/posts/96-scss-sass-is-a-css-extension yet and are interested in an abstraction that will help with the vendor-prefix maintenance nightmare we currently have give it a look. Also check out the newly added @”extend property”:http://nex-3.com/posts/99-selector-inheritance-the-easy-way-introducing-extend.

    One thing I still fail to understand is the timeline for when these prefixes should be removed. It’s all well and good for features to be designated as “in progress” by vendor-prefixes, but nobody is regulating how long we as developers will have to support them in our code.

  24. Great article Eric.
    I agree with you on all your points.

    Although it initially means more coding to get the desired effect, due to the Cascading nature of the Style Sheets – as each browser is ‘permitted’ to support the standard prefix-less format – as long as the standard one is last in your CSS then you wouldn’t even need to remove the vendor specific ones.

    Of course removing the surplus declarations is preferable, but in a situation where a client considers their website finished and is unwilling to pay you just to ‘clean-up’ – nobody loses out to any large degree.

    Are the conventions for the prefix set?
    In theory, would I be able to code in -ms-whatever even if IE hasn’t started trying to implement the feature yet – so that when it does, my implementation of whatever would work (albeit with unpredictable results).

  25. On the one hand, the author’s method of certifying new attributes would encourage browser vendors to more quickly come to a consensus on implementing the specification as there would be very little incentive for them to work toward anything else. We could see shorter periods of less severe browser inconsistencies.

    On the other hand, there may be a detrimental effect on innovation from the browser manufacturers. For instance, what if Webkit’s drop shadow implementation is just better than everyone else’s? The specification and other vendors could implement it, and everyone benefits from Webkit’s idea. But if Webkit is trying to implement the specification as it is developing, focused only on certifying the feature in the end, they may not choose that it is more worthwhile to stick close to everyone else than to innovate. Let’s not forget that the technology behind AJAX came from browser innovation.

    Such a system as the author proposes, would encourage browser makers to implement the standard as quickly as possible. Thus, more attention would be paid to the specification in progress, and the browsers’ implementations would stick closer to it even before it is finalized in anticipation of being quickly certified. I believe there is plenty of time for everyone to stick to the same standard when it if final, but as it is emerging variations can help tease out behaviors and functionality that were previously unknown.

    In my view the early days of new features and attributes are the territory for pioneers, be they web designers/developers, web standards groups or browser manufacturers.

  26. Even though I agree with parts of this article, Eric’s explanation turns CSS from something most people could learn into something for freaks only.

    Following the implementations of 5 rendering engines for each property is craziness. Keep going back to sites to check changed behavior is even worse.

    You say that vendor-prefixes imply wip properties, but the reality is that people are not perceiving them as such. They see the nuisance, but they don’t see that their behavior can change or be dropped overnight.

    I still believe these prefixes have a right to exist … in nightlies and experimental builds. In production browsers they cause lots of confusion and even though you can warn people about the dangers, you know the majority is not going to listen. Looking at the past, you just know they’re going to cause us a whole lot of trouble in the future.

  27. This might be a workable solution for now, but this is surely the path to insanity. This doesn’t even start to cope with one of its first examples – what happens when a vendor changes the implementation of a feature as the standards evolve? You have no way of selectively defining behaviour.

    Also, who decides when the vendor can drop the prefix in favour of the final property value? The implementation would be up to the vendor, and they would be the ultimate determinator of whether their browser conforms (because they control whether to process the prefixed or non-prefixed version).

    Sure dear reader this is what media queries is designed for? Granted that media queries currently has non properties to support browser vendor, version or W3C specification level as supported media properties. But surely that’s why it should be there.

    The presentation of CSS properties is a function of a browser version, so the only way to resolve browser differences is to provide a mechanism to select browser versions in the CSS specification.

    Both Less-CSS and Sass seem to be trying to achieve the same thing – fixing a broken specification. Perhaps what is needed is something more akin to scripted stylesheets – JCSS anyone?

  28. I understand why people rebel at the idea of four rules for each rendering engine, followed by the “unprefixed” rule.

    But the fact is, it’s not mandatory to use rounded corners, gradients or whatever the flashy technique du jour is.

    As I said on my own blog http://www.brucelawson.co.uk/2010/cross-browser-future-proof-css-3/ :

    If you as a developer choose to use experimental, pre-standardised code on a production site, then you need to live with the consequence of that choice.

    There’s no getting around it: experimental, pre-standardised code is susceptible to change. If the specification changes, you’ll need to change your CSS (which is easier to do if it isn’t being hidden away by some library).

  29. Very well written article, thank you.

    Also want to try SASS (as I read in the comments) for I believe it is the great step further in the CSS world.

  30. Oops, I should apologise for my opening comment on the article. It was poorly worded, and written before I’d given the article the time it deserved. It’s the kind of comment I hate reading and it probably came across as really ignorant – sorry.

    Eric, I do think that the approach you describe is right. The only logical conclusion for having a prefix system where an implementation can ‘graduate’ into a non-prefixed form, is to have a fixed list of criteria to compare an implementation against.

    However, I still have issue with a couple of the points from the article:

    Firstly, I wasn’t sure whether you were suggesting that the working group would formally ratify each prefixed implementation, or whether the presence of published tests would be sufficient for vendors to decide that they could drop the prefix.

    Secondly, it seems like what you are leaning towards is a system where individual properties reach an effective Candidate Recommendation state separately, rather than as a whole Specification (or module in the case of CSS3). In the current W3C model, it’s not advised to implement non-prefixed properties until they are recommendations – the assumption being that at that stage they’re still potentially open to change.

    I was imagining a -beta- prefix would work exactly as you described, but taking this Working Draft state into account. So, vendors would use the -beta- prefix once they matched up to the complete-but-not-ratified set of tests, and at a later date the -beta- prefix would be dropped for the entire spec at once.

    On the other hand, if you think that a unified set of tests per-property should be enough to formalise the syntax and behaviour of that property forever, *without* having to wait for the entire spec to be ratified, then I do agree with what you suggest.

  31. Niels: “Following the implementations of 5 rendering engines for each property is craziness. Keep going back to sites to check changed behavior is even worse.”

    As more browsers correctly implement the standard (which *must* override the vendor specific) are you _really_ going to go back to strip out the excess? What if the user hasn’t upgraded to the version a browser that now works?

    Commercial sites are normally designed with certain versions of browsers to support as a baseline. When these sites are redesigned the baseline is reassessed according to what is currently used (from demographics), so the old site might have worked in IE4 but the new site doesn’t work in IE < 7. In a few years time and the next redesign, all browsers could implement all the funky stuff so no vender specifics would be needed. (except for the new funky stuff that isn't standardised of course) Bruce: "But the fact is, it's not mandatory to use rounded corners, gradients or whatever the flashy technique du jour is" It is mandatory if the client thinks it is, mainly because they've seen some app on their iPhone and like the look. The fact that it is a pain to do well is why you get paid. Or they'd do it themselves with a copy of Dreamweaver.

  32. kyangareth: Yes, in this conception, the Working Group would declare a given property’s implementation to be interoperable and thus able to drop the prefix. Upon doing so, it would also formally mark that property as being interoperable. (And if there were only one implementation of a given prefixed property, it would stay prefixed forever.) The method the WG uses to reach that decision would be up to it, but I would strongly favor test suites that any implementor could run through to show interoperability. Whether they’re automated or manual doesn’t really concern me; either is fine, though automated is obviously less work to evaluate at the cost of (marginally?) more work to construct.

    To the second part, what I envision is that any module which seeks to reach CR stage needs to have all of its constituent properties exist somewhere in an unprefixed state. I don’t think they would have to be unprefixed in all the same browsers, although I wouldn’t oppose that requirement either. Basically, any property which has no unprefixed implementations would be enough to keep a module out of CR. Either it would have to be dropped or interoperably implemented.

  33. Justo, you’re right that the WG doesn’t certify browsers, but it does need to certify—at least abstractly—interoperability. This idea would shift them to more directly certify interoperability of a given property. So in that sense, yes, they’ll certify browsers, but on a per-property basis. Since declaring interoperability is a requirement to advance a module in the W3C Process, it makes sense to me to do so more directly.

    And yes, extensive test suites would be required. I view that as a good thing: maybe the best thing. Test suites are the best way to define what a property does and what it means to be interoperable. Vendors and the WG are already convinced of the usefulness of tests, so all this would do it increase the incentive to create and debug them.

  34. A few people (including Eric) have misunderstood comments in “my piece”:/articles/stop-forking-with-css3/ regarding vendor prefixes _vis a vis_ CSS hacks. I apologies for any lack of clarity on my part, but I was trying to say that prefixes are _like_ hacks because they are both means of forking. I don’t think that vendor prefixes are hacks and, in fact, I agree with Eric’s premise in this piece 100%. Vendor prefixes are a necessary part of the standards development process, eCSStender just allows a saner approach to dealing with them by facilitating the equalization of disparate implementations (vendor prefixed or not).

    If nothing else proves my thoughts on the matter, the fact that eCSStender supports the creation of new vendor prefixes for experimentation with the future of the language should.

  35. Loved the article (as well as the Do Not Fork article).

    I agree that we need a way to keep the language evolving and allow for new features to be used even though they aren’t officially ‘in the spec’ or supported across the board.

    However, the more and more we put prefixes and hacks into our code, the worse and worse it will be for maintenance of that code. We already have sites breaking because they use the <!–[if IE] conditionals and never accounted for the later versions of IE being ‘fixed’.

    I just worry that the more and more we hack up our code (especially in large-scale corporate usage)- the worse and worse maintenance nightmare we will create. IMO hacks should only be used if there are no other alternatives around a problem, and need to be thoroughly documented – just like any ‘hack’ in software engineering should be.

  36. Oh snap, say Hello to a new era of hacks and proprietary code!

    Propagating browser specific hacks is not only wrong, its dangerous. More so when done by someone people look up to like Eric Meyer.

    Ten, twenty or fifty lines of “temporary” code per project that “should be removed” months or years later when an implementation is final?

    Whats the point? Rounded edges? Shadows? Thats not even remotely vital to a project but pure icing. Those things can be accomplished through other, standards compliant means like images and we’ve been doing so for years.

    Even proposing this shortsighted approach would create a huge uproar among say programmers, architects or fashion designers.

    My 2 cents.

  37. Why can’t we have vendor prefixes and the unified prefix at the same time?

    Then we specify the unified prefix as you would normally:

    #box {
    border-radius: 10px 5px;
    }

    If you later find out that, say IE, isn’t working how you are expecting it then you can modify your css accordingly – overriding the style for that browser:

    #box {
    border-radius: 10px 5px;
    -ie-border-radius: 5px 10px;
    }

    This way we assume they are implemented correct until proved otherwise.

    The current way we are just going to end up waiting 5 years odd whilst the older browsers gradually fade away before we can remove those vendor specific prefixes.

  38. As many sites I build are short-lived but required to work in as many browsers as possible, I am only using them to add flair that degrades for browsers that don’t support the feature.

    If you have a recent browser, everything will look nicer, but work just the same as it would were you stuck on IE6. I do wish Microsoft would backwards patch IE6/7 to support border-radius, though. I work with companies who are stuck on older browsers for weird bureaucratic reasons.

  39. As a relative newbie (4 years experience) to web development and CSS, I loved the article – well written and giving a great history lesson. I’ve also loved reading the comments – informative and giving great debate.
    To add to the great prefix debate, I am in a privileged position as a newbie; such that I can look at the situation with fresh eyes, and not those that have been tarnished by the Box Model.
    As I see it, this problem is not confined to CSS, but is in fact representative of a bigger problem – the quest for Utopia.
    People have searched for Utopia for millenia and never found it. In our ideal CSS Utopia, every browser would display CSS the same way, all the time. All browser changes and updates would be implemented at exactly the same time, in exactly the same way. Is this ever going to happen? No.
    So we need to address that. And in the same way that we all use IE hacks, the idea of browser specific hacks (which is basically what prefixes are) is perfectly logical.
    I noticed other people’s comments worrying about maintenance of the stylesheet and the website. Well as we do now, we can create a “master” stylesheet, and then create separate browser specific stylesheets for the various prefixes. So one stylesheet called iehack.css, another mozhack.css, etc. Maintenance of the website then becomes maintenance of these browser specific stylesheets. In time, as Eric points out, these stylesheets will become redundant as browsers implement new CSS rules correctly.
    Alternatively, as Eric points out, we could simply omit the rounded corners from the “master” stylesheet, and use browser specific stylesheets to add them to whichever browser we wanted.
    As long as people use different browsers, and hang-on to old ones like IE6, we will need to use hacks and treat different browsers as…different.
    It may seem painful and like a lot of work, but this is reality. There is no CSS Utopia – there never will be. And so to me, prefixes seem like a perfectly logical step into making our expanding CSS world a cleaner place.

  40. Florian – if you follow the cascading method, the final declaration, below browser-specific implementations, would be the standardized syntax. Therefore, when a recommendation is finalized and browsers support it as it should, it will already show up properly. If you’re interested in saving a few kB of space you can go back and delete the old code, but it’s silly. And then the older browsers won’t be able to see it.

    Eric – excellent article! Thanks for the clear explanation. It’s definitely a great way to continue moving forward. Tedious, but at least it will create a better form of communication.

    Imagine we could have done things like -ie6-margin-right instead of the star hack! (I know, it would really be -ms-, not version-specific!)

  41. I think a lot of the craziness of multiple prefixes can be greatly reduced by saving your stylesheet as a php file, and declaring a variable like so:

    $border_radius_5 = “border-radius=5px; -moz-border-radius=5px; -webkit-border-radius=5px;”;

  42. with one thing that actually spoiled the whole message of it.
    Netscape supported box sizing model in NN4, IE4 copied this functionality. In 1997 2 browsers with 98% of market share supported either box sizing model or no model at all (previous versions of NN and IE). So there was solution, in 1998 W3C should recommend box sizing model instead of content sizing model and we would have not spent decade in nightmare.

    But to the point of this article. Any unification (e.g. -beta) would solve only one problem: more coding, but introduced new one: inconsistence in implementation yet again. So no solution at all.

  43. Although I am a fan of this site and also of Eric Meyer’s work (I use his CSS reset regularly), calling him a “King of CSS” is a tad sensational, no?

  44. First and foremost, this article was spot on Eric – it’s much better for designers / developers to have the ability to specific browser specific behavior than be forced to program in hacks.

    I have once concern though. The notion of browser makers proliferating prefixes presumes that they *want* to be compliant and interoperable. So what happens when a browser maker stops caring about standards compliance and interoperability?

    Consider IE’s non-standard rendering engine. Microsoft had a huge obligation to their existing customers, especially those with support contracts. Customers had written a lot of software that *depended* on IE’s non-compliance, and they were paying Microsoft a lot to keep that software running smoothly. The fact that IE wasn’t compliant just wasn’t an issue from their perspective. (Their overwhelming control of the browser market certainly didn’t help the issue – since so many people were using IE, designers *had* to take it into account regardless.)

    This isn’t just an issue for companies who have a lot of existing customers to support, it’s also an issue for those who are extremely innovative, like Apple. Browsers (and plugins) have always lead W3C in terms of the technology (ie, video and rounded corners), so it’s not hard to imagine that they would come up with something really innovative, gather a lot of support around it, and then refuse to implement the spec because their own implementation provides a better experience for people using their other software and / or devices.

    In the long run, W3C is like the old man of the Internet. Since it’s got no commercial interest and no competition, it can spend the time to reflect and garner a perspective about the way things should be. Unfortunately, it’s really got no power to compel people to listen – the best it can do is try to persuade.

    Browser makers on the other hand are in the exact opposite boat – they’re surrounded on all sides by those who would seek to destroy them and (generally) investors demanding a return. They have to do whatever it takes to stay afloat, including walking away from the standard when it doesn’t suit their needs.

  45. I disagree completely with this article.. it is absurd.. imagine FF, IE, Opera, Safari etc all having their OWN -moz, -ie, -op etc codes.. we would then have to repeat same thing n times to get them to work in n browsers…

    instead I don’t see why if a browser gets something wrong, they can issue a WARNING a month or two prior saying they got xyz wrong (ie IE could have said they got box model wrong) and post a detailed explanation and give a time limit of TWO months or whatever is appropriate (hell even 6 months – 1 year) for web masters to CHANGE…

  46. Although I agree with most of the article, and would like the idea of browsers to get certified as some point, I’m not sure if that is really practical. Instead, doesn’t the current system work well enough — let the community feedback do the work?

    The purpose of a prefix is to allow the STANDARD to change while it moves from first proposal to an agreed-upon standard. The purpose of a prefix is not to test the browser’s implementation: that is what the beta testing phase is about. It doesn’t make sense to me to mix the two.

    So when there is a new feature accepted as a standard, browsers should be allowed to implement it, and have their beta testers verify that their implementation actually is the correct one. Web site developers can either use browser-specific implementations of a draft feature using the prefixes, or wait for the standard and only use that.

    Of course, this would all assume that the standards themselves are written clearly so that people will recognize a correct implementation when they see it. However, that isn’t really very different from expecting a standards committee to recognize a correct implementation when they see it (by having them certify implementations).

  47. Honestly, we all hate the work involved in remembering to make that darn curve work in multiple browsers but in the end if it makes the site look good. It it worth it?

    As far as doing more markup vs. more css. I’d take more CSS any day over bloating the code.

    As far as an alternative (and keep in mind I’m saying alternative and not better way) would be to use graphics for your gradient. Yes it’s better to have everything coded but with a graphic you’re almost guaranteed that it’ll view the way you want if your divs are correct. And if you optimize the graphics they can be real small and still look sharp.

    Just my two cents.

  48. I personally don’t mind the concept of browser prefixes. However when thinking objectively about them, the do feel basically like sophisticated hacks. It’s a shorter and cleaner way of browser sniffing (and it works better). But like I said, I don’t mind writing them.

    However, I do think that a unified prefix could be beneficial for everyone involved. First and foremost, it reduces file size, which means faster load times, which Matt Cutts has recently mentioned is becoming a factor. Secondly, while we all would love to be our clients’ web designers from now until the day the internet is turned off, it doesn’t always happen that way. I have a handful of clients who I have not heard from since I received final payment from them. In these instances, while I agree with you Eric that vendor prefix usage will dwindle overtime, this will only occur if we as the designer are still involved in the site. If we are no longer in the loop, the client is stuck with extra code that is only slowing down their load times.

  49. shez,

    Its not about browsers fixing themselves in a given time span. Its about users. Any time a new browser is released, users start using it–and they don’t stop using it.

    I would much prefer prefixes over exploiting parser differences.

  50. Insightful article! I liked your observations about the experimental nature of working with CSS3 in its early stages—that designers should expect various browsers’ implementations of CSS3 properties might change over time—as well as the careful ordering of rules, from vendor-specific to general.

    Here are my thoughts on how the current system could be modified for the benefit of CSS designers and developers:

    1) Allow the use of vendor-specific prefixes to target browsers at ANY stage of CSS implementation.

    Browser differences are invevitable and, from time to time, need to be accomodated. We already have conditional comments for IE; why aren’t we able to target other browsers when necessary? Adding a vendor-specific prefix to a rule and placing it AFTER a general (or conflicting) rule could accomplish this quickly and easily.

    line-height: 1.1em;
    -o-line-height: 1.2em;

    2) Create a -beta prefix (maybe just a hyphen by itself?) to target new properties, with the option to override via vendor-specific prefixes.

    This approach could offer the best of both worlds: simplicity, with an option for specificity. When differences between implementations of a new CSS3 property are negligible, designers could rely on a single rule:

    -beta-box-shadow: 0 3px 10px #aaa;

    Or even simpler:

    -box-shadow: 0 3px 10px #aaa;

    When implementations are not so compatible, vendor-specific prefixes could be invoked:

    background: -moz-linear-gradient(top, #223344, #6c7782) repeat-x;
    background: -webkit-gradient(linear, left top, left bottom, from(#223344), to(#6c7782)) repeat-x;

    An obvious question regarding a broader application of vendor-specific prefixes (allowing them to denote both experimental and standardized versions of a property) is: Could this cause a design to fail once the specs/implementations change? Your article seems to respond by suggesting that such changes are to be expected regardless. Moreover, I suspect that careful placement of a more general rule would distinguish one case from other, and render the first case harmless:

    a)
    -ms-text-curl: minor;
    text-curl: minor;

    b)
    text-curl: minor;
    -ms-text-curl: minor;

    On the other hand, perhaps notation should more accurately reflect intent? In that case, vendor-specific prefixes (e.g., -ms) would best be used to target browsers, a beta prefix to target experimental CSS properties, and a combination of the two to target browser-specific, experimental implementations:

    -ms-beta-text-curl: minor;

    Much ado over a minor text-curl, huh?

  51. One major flaw in all this is the assumption that once a new browser is available, everyone will flock to and download it. I believe the persistence of IE6 is a testament to what will likely happen. A less extreme example can be found by digging through your analytics. I know I still see plenty of early builds of Firefox that have spotty prefix support at best.

    So, what’s the problem you might ask? How long do we leave the prefixes in our code? You talk as if one day in the near future everything will be all green fields and summer time, skies the purest blue, and web developers all frolicking as if Pan himself. I think it’s more likely that these prefixes are a more permanent feature of our CSS and thus less of a temporary fix to a problem, the working group not working fast enough.

    Interestingly enough, I see Safari being updated in my analytics at a much faster pace then anything else and that’s because Apple throws Safari updates in with OS software updates. Oh, if another vendor in Washington State cold get away with the same thing without getting a bunch of geeks panties all in a bunch, what a world that would be. We might be closer to your green fields and summer time, blue skies and frolicking.

  52. One problem with the vendor prefixes occurs when you access prefixed properties through JavaScript.

    In every browser, a dash indicates that the next letter of the property name in JavaScript is a Capital Letter. So “border-radius” becomes “borderRadius” in JavaScript. The same is true for vendor prefixes. “-moz-transform” becomes “MozTransform”. That makes it pretty easy to create a name translation algorithm.

    …if it weren’t for IE. IE does this differently. I discuss this at “my blog”:http://blog.attrakt.se/2010/11/browser-prefixes-in-ie-are-different.html

  53. I agree prefixes are better than all other options when different browsers use the same property differently.

    However, they are better because they are the lesser evil, which doesn’t make them better in the true sense of the word.

    There should be homogenous syntax in all browsers. Vendors are to blame here: it’s not that much of a complication to talk with eachother and do things the same way. Declaring gradients with positions first and colours later and vice-versa isn’t something that is complicated to unify. It’s not like vendors have to change the whole rendering engine, just how they parse parameters p1=position, p2=colour. EASY. They just have to discuss and think about what the Open Web is all about, because I can tell you it’s not about petty rivalry. They aren’t suppose to be first to the finish line to “sell” the product first. No one will “buy” Mozilla because THEY have rounded corners nailed and others don’t yet. It’s a different market.

    As for “you can drop the prefix once all is good” part, that will never work. You can’t trust people to always have the latest version of a browser. Just think of the high percentage IE6 still owns after what, 10 years or so?

    However, this WAS a very good article. So thank you.

    Stick a fork in me, I’m done.

  54. I have very simple idea. If any browser implementing new property would parse prefixed version as well as the non-prefixed version from the very beginning, than we could just stop to use the prefixed properties *until* we see that anything brakes. If for example new property text-curl is proposed then we just use

    text-curl: minor;

    in our stylesheets and wait what happens. When browsers start to implement the behavior properly, than we do not have to do anything. If for example IE implements it with bugs, then as soon as we read about it in designers blogs we just use the prefix to correct it by saying

    text-curl: minor;
    -ie-text-curl: normal;

    Yes, I am suggesting to put the prefixed version *after* the normal one, so we can override the behaviour for buggy browser.

    Before you start to criticize the idea, think about it – in fact this is exactly what we are already doing by automatically use the four different prefixes for any new property introduced. By writing

    -ie-text-curl: minor;
    -moz-text-curl: minor;
    -webkit-text-curl: minor;
    -o-text-curl: minor;
    text-curl: minor;

    we just say “I hope that everyone is implementing the property correctly” and only if/after we find out a bug we are correcting the css. So why not use the same approach with much less hassle?

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA