Two New Proposals to Solve the CSS3 Vendor Prefix Crisis
Web developers have been concerned about the vendor prefix crisis since February 2012. To summarize the issue, this is what should happen in an ideal world:
- Vendors implement experimental CSS3 properties using their own prefix, e.g. -webkit-transform, -moz-transform, -ms-transform, -o-transform.
- Developers can use the technologies today without breaking cross-browser compatibility. Properties can be listed with their prefixed and unprefixed names to ensure they work everywhere.
- Once a property becomes a W3C recommendation, all browser vendors can provide a stable unprefixed property, e.g. transform.
- Optionally, developers can remove the prefixed properties from their stylesheets. However, it’s not strictly necessary if the unprefixed property is defined last and CSS cascade rules apply.
This is what occurs in the real world:
- Vendors implement experimental CSS3 properties using their own prefix. In some cases, vendors promote them as an HTML5 “standard” even if they’re device-specific or never submitted to the W3C.
- Some developers use the proprietary property from a single vendor, e.g. only -webkit-transform. This might be owing to ignorance, laziness or because they’re testing a limited number of devices.
- Once a property becomes a W3C recommendation, all browser vendors can provide a stable unprefixed property, e.g. transform…
- but developers neglect to change their stylesheets. The site looks good in some browsers but worse in others even when they support the standard W3C specification.
- The vendors become concerned and add support for other prefixes into their browser, i.e. Opera implements the -webkit prefix for some properties. The prefix process is broken and, while it’s too early to predict the outcome, the majority of developers consider it to be a bad move.
We have discussed the issues at length on SitePoint; there are no easy solutions. However, two interesting proposals have been raised by W3C members during the past week.
Option 1: Unprefixed Properties are Supported From Day One
The first proposal comes from Florian Rivoal, Opera’s W3C representative:
When a browser vendor implements a new CSS feature, it should support it, from day 1, both prefixed and unprefixed, the two being aliased. If a style sheet contains both prefixed and unprefixed, the last one wins, according to the cascade.
Authors should write their style sheets using the unprefixed property, and only add a prefixed version of the property (below the unprefixed one) if they discover a bug or inconsistency that they need to work around in a particular browser.
If a large amount of content accumulates using the a particular vendor prefix to work around an issue with the early implementation in that browser, the vendor could decide to freeze the behavior of the prefixed property while continuing to improve the unprefixed one.
For example, you could use the following transform code in your CSS:
The property would be ignored by all browsers which had not implemented transforms. If there were a difference between two or more implementations, e.g. webkit browsers rotated anti-clockwise by default, you could override the property accordingly, e.g.
transform: rotate(30deg); -webkit-transform: rotate(-30deg);
It’s a simple solution and easy to implement. Most existing stylesheets would continue to work and prefixed properties would rarely be necessary. In most cases, you would never need to update your CSS again.
However, what would happen if webkit changed rotation to the W3C-approved clockwise direction? Developers would need to fix their stylesheets by removing or rearranging the
-webkit-transform: rotate(-30deg); property. Unfortunately, not everyone uses the same version of the webkit engine at the same time. You could encounter a situation where your site works in Chrome but not in Safari for several months.
Option 2: A New Vendor-Draft Modifier
The second proposal comes from François Remy:
Let’s introduce the “!vendor-draft” value modifier. I propose we use unprefixed properties from start, but with a token explaining which version of the property we built our CSS for:
border-radius: 3px !webkit-draft;
Any browser which is not webkit but implemented border-radius in a way that is compatible with the “webkit draft” can support the declaration. This is different from vendor prefixes: other browsers don’t impersonate webkit, they just acknowledge they support one specific property the way the webkit draft defines it. Browsers which are not compatible with that draft will just ignore the declaration. Browsers that change their implementation of a property are encouraged to iterate their “!vendor-draft” flag (using a version number, if appropriate).
This solves the issue by changing the property value rather than its name (in a similar way to the
!important modifier). Again, the following transform code could be used:
But a default anti-clockwise rotation could be fixed in any browser adhering to a webkit specification:
transform: rotate(30deg); transform: rotate(-30deg) !webkit-draft;
If a browser subsequently supported the W3C specification, the second property would be ignored.
It would also be possible to implement draft versioning, e.g.
transform: rotate(30deg); transform: rotate(-30degrees) !webkit-draft; transform: rotate(-30deg) !webkit-draft-2;
It’s a flexible solution which finally addresses the issue of properties evolving over time.
Unfortunately, it’s more difficult to implement and could take months to appear in browsers even if all vendors agreed today. It may be technically better, but it’s a fundamentally different approach which could break existing stylesheets. In the short term, vendors would probably support both prefixes and value modifiers — and that would lead to confusion.
I like both solutions. From a coding perspective, vendor-draft modifiers seems the most logical option but I doubt it can be considered until vendors “complete” CSS3 and begin work on CSS4.
Supporting unprefixed properties is more practical but will certainly cause versioning issues which couldn’t be fixed in CSS alone. But perhaps that’s the price you pay for using experimental technology?
Do you have a preference for either of these options? Or is it too late to prevent a vendor prefix catastrophe?