Vendor Prefixes: The Good, The Bad and The Ugly

Back to Articles
Article Image
Author
Article Image

If you're a forward-thinking web developer, you must be pretty familiar with code that looks something like this:

.foo {-moz-transform: rotate(45deg);-ms-transform: rotate(45deg);-o-transform: rotate(45deg);-webkit-transform: rotate(45deg);} 

The same property, repeated four times but with four different prefixes, one for each of the four main browser rendering engines (these are known as vendor prefixes). It seems wasteful; all four operate in exactly the same way, so all this means is extra work for us and a lot of repetition in our stylesheets. Unsurprisingly, a lot of people are calling for these prefixes to be scrapped. In a post which began a round of discussion recently, Henri Sivonen said:

I think vendor prefixes are hurting the Web. They are hurting Web authors. They are hurting users of browsers. They are hurting competition in the Web browser space.

This divided opinion. Daniel Glazman disagreed in a point-by-point rebuttal, but Alex Russell was more emphatic still, saying "vendor prefixes are a rousing success":

Prefixes are an enabler in allowing the necessary process of use, iteration, and consensus building to take place.

So I'd like to provide a little context to the debate, as well as put my own opinion on the relative success of vendor prefixes.

WHAT ARE VENDOR PREFIXES FOR?

In the past they were mainly used for features that were proprietary to each particular browser, but in recent years they've become more common as a way to introduce experimental support for new CSS properties, before they become standardised. The aim is that no browser introduces a new feature before it's been found to be fully interoperable with other browsers.

As an extreme example, imagine we introduce a new property called dangle which takes a single angle value, like so:

.foo { dangle: 45deg; }

Seems straightforward, but what if WebKit measured that angle vertically, and Mozilla, horizontally? If the two implemented the property without a prefix, the feature would be interoperable; in one of the two browsers it would display completely differently to how you wanted it.

Browser prefixes are intended to save us from that problem, and when they do their job, they do it very well. For a real world example, consider the radial-gradient property. This is how the syntax looked when WebKit first introduced it, used to create a circular black to white gradient from the top left corner with a 100px radius:

gradient(radial,0,0,0,0,0,100,from(black),to(white);

Not to put too fine a point on it, it was ugly. As the syntax currently stands, you have to do this to get the same effect:

radial-gradient(0 0,circle,black,white 100px,transparent 100px);

But there's a new, refined syntax on its way, which does the same like this:

radial-gradient(100px circle at 0 0,black,white);

The syntax has undergone radical changes since first being introduced, it's much more logical and human-readable now, and it's thanks only to the browser prefixes being used that we haven't ended up with a load of incompatible properties across different browsers, causing us (and therefore our clients) no end of problems.

So you can see how prefixes are useful in this example, but the complaints tend to come when we have the opposite; as in my first example, where we have four properties working in exactly the same way, seemingly standardised but not available for us to use yet.

That's down to the way the W3C works. Their criteria state that features are deemed to be experimental until the module they belong to has gained Candidate Recommendation status. This means the technical reviews have been completed and there are no outstanding objections, which are things we don't always get to see; while it may appear to us that the feature is ready, there may be very good reasons why it isn't.

THE REAL PROBLEMS WITH BROWSER PREFIXES

Other than making our code messy and repetitious, there are two serious problems being caused by prefixes in the form they currently take.

The first is that developers love to experiment with cutting edge features as they're released, creating demos to show off their potential. But sometimes a feature can be implemented in one browser years before it appears in others, as was the case with CSS Animations. When that happens, those demos aren't always updated to accommodate the new vendor prefixed property, meaning that in new browser versions the demos simply don't work even though it seems as if they should - which looks like the fault of the browser, not the developer.

The other problem occurs when developers use prefixed properties in a way that, deliberately or otherwise, means the targeted browser is the only one that can display the site correctly. I'm thinking specifically of WebKit properties on mobile here; it's unfortunately the case that some developers make mobile websites using -webkit- properties only, meaning that alternative browsers - such as IE9 Mobile, Opera Mobile, Firefox for Android - get a broken or non-existent experience. This is an example where browser prefixes lead to a browser monoculture which is actively harmful.

The situation has become so bad that some browser makers have considered implementing -webkit-properties just so that their users can browse the web without problems. Should this happen, this would break the vendor prefix system once and for all.

SOME PROPOSED SOLUTIONS

Many people have suggested ways to replace the vendor prefix system: Henri Sivonen suggested in his original post that experimental features should be kept in nightly and development releases of browsers, and not make their way into full releases until they are stable. Lea Verou suggested a number of different approaches, including using a single experimental prefix but applied per-browser using an @vendor rule, and Felipe Gomes has a similar suggestion, using the @vendor-unlock rule to activate experimental properties.

However, all of these people believe that the vendor prefix system is more fundamentally broken than I do. I think the problem is a little more obvious, as you'll notice that both of the key problems I described previously have a clear commonality: developers. Us. As Opera's Bruce Lawson said:

We're approaching a monoculture on mobile. This is not the work of an evil organisation, but it's developer-constructed.

In a post on this subject on my own blog, I argued that we need to take more responsibility, including:

  • Commit to supporting old demos that we have made.
  • Always make sure we plan our designs and builds in a way that they are not reliant on prefixed features, but degrade gracefully.
  • Don't use an unprefixed property before standardisation has happened unless we can have reasonable confidence that it is safe.

Even if you're an advocate for a more fundamental revamp, you should agree that a change in our behaviour could be massively beneficial to the web as a whole.

Of course, there is another option: don't use vendor prefixed properties at all.

BONUS SECTION: TOOLS

If you get bored writing out all of the prefixes individually, there are tools such as Prefixr and CSS3 Please!which allow you to write the rule once and have all the code output for you.

An alternative approach is to use tools which pre-process your stylesheets, either on the client side like -prefix-free or LESS, or the server side like Sass. Note that the former two introduce a dependency on JavaScript, which may be less than optimal.

Post a comment
Your Screen Name
Your Email Address
Your Comment
Recent