Writing cross-browser, future-proof CSS 3
Here’s a quick tutorial (actually, rant) that came out of an aside I mentioned when doing my talk for Future of Web Design two weeks ago.
It came about when I was using the IE9 preview to test some sites. I noticed that a site that boasts rounded corners didn’t appear to have them in IE9, even though IE9 allegedly has border-radius support.
“Silly IE9”, I thought.
Wrong. Silly developer.
The difference between a pro developer and a wannabe is that the pro developer makes sites that are cross-browser and, as far as possible, future-proof. By contrast, the wannabe assumes that everyone is the same as him and therefore if the site works on the browsers he uses, that’s enough.
Our wannabe developer’s code looked like this
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
By using only vendor prefixes, the wannabe developer ensures that this nice part of the design will only work on those browsers.
A pro, however, cares about his client so doesn’t leave them with a site that will need changing later. A pro cares enough about his site’s users to give the design to their browser and let it do with it as it will.
How?
Simply by adding the non-prefixed cross-browser version of the property, he can add border-radius support for IE9 now, Opera now and any new browser that comes along in the future:
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
border-radius: 6px;
In the above example, border-radius is pretty mature, so IE and Opera jumped straight to using the standard prefix-less property, but other fancy CSS 3 properties are implemented only with vendor prefixes at the moment. Note I said “at the moment”; in two years’ time, a new browser may consider that feature stable enough to implement without a vendor prefix and, because you’re a pro rather than a wannabe, you want to ensure your code works in 2 years time as well as today.
For maximum compatibility, I advise adding all vendor prefixes (I do it in alphabetical order to help me remember) plus the non-prefixed version.
So here’s a version that future-proofs and cross-browserifies™ CSS3 transforms:
-moz-transform: scale(1.6);
-ms-transform: scale(1.6);
-o-transform: scale(1.6);
-webkit-transform: scale(1.6);
transform: scale(1.6);
If, for example, IE adds support for the prefixless version, or uses the -webkit- version, you have one line—27 bytes—of redundancy. So what? And now your code works everywhere that has support, today and tomorrow.
And that’s how it should be.
I feel very strongly that using JavaScript to remove all that extra CSS away is a bad idea. Apart from the absurdity of using “20kb minified js to avoid 5kb ‘untidy’ CSS” (as one person commented about eCSStender), it’s ducking responsibility. 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).
See -o- vendor prefixed CSS supported in Opera 10.50, also Vendor-prefixed CSS Property Overview which compares vendor prefixes across browsers.
Resources
(Added Nov 2011)
- Prefixr – web utility that adds all the prefixes for you
- MSDN: A Best Practice for Programming with Vendor Prefixes
(Last Updated on )
Buy "Calling For The Moon", my debut album of songs I wrote while living in Thailand, India, Turkey. (Only £2, on Bandcamp.)
20 Responses to “ Writing cross-browser, future-proof CSS 3 ”
Have been doing this from day 1 with CSS3, and assumed everyone would be out of (rather obvious?) common sense.
The woes of early adoption.. Five rules for one.
I’ve used SASS to help limit the repetition of proprietary rules but it makes me feel sick to the bottom of my don’t repeat yourself stomach.
Progress eh?
I also put the vendor-prefixes in a separate stylesheet. In my standards compliant css files I am using e.g. “border-radius: 10px” and in the vendor-prefixes.css I’m using the same selector and write -moz- and -webkit-.. I think that makes the code cleaner..
This is a difficult tradeoff. Using the unprefixed version prevent later changes to a spec. Of course, for border-radius, there’s no question today, Opera and IE handle the unprefixed version. But for a long time, the two only implementations were different. So which syntax should you use with an unprefixed version ? The Mozilla or WebKit syntax ?
Same for CSS transforms, it’s a rather new spec and it might change a lot. CSS gradients is already very different in Gecko and WebKit. So I’d rather forget the unprefixed version and ensure that every browser has a good enough fallback.
Bruce, transform and transition syntax will change, accoding to Alex and Hokon (W3C, you know) so it’s a bit dangerous to use this properties without prefixes.
For the sake of code readability, maybe we should write the non-prefixed cross-browser version of the property first (?)
which syntax should you use with an unprefixed version
– Rik
The one that’s in the CSS3 Working Group’s specification. If it’s not specified at all yet, the one you like better.
What? What other criteria might you have?
Right, the specification isn’t finished. Of course, it’s subject to change. But you work with what’s there at the time you write the code. It might not change, or it might not change significantly! But even if it does it’s the final authority on CSS3 at any given point in time.
a bit dangerous to use this properties without prefixes
– Vadim Makeev
Um…How? Prefixed CSS3 properties are in development every bit as much as the specification is and as such are subject to changes in syntax, changes in implementation, and (presumably) eventual obsoletion.
I recall reading in an older CSS specification that properties starting with a – (dash) are reserved for vendor specific or in development properties. That’s…just what they’re for.
So if you’re dealing with a CSS3 property that’s under development it’s not “dangerous” to use the property without the prefix, it’s exactly what you and the browser are each supposed to do when it’s not under development anymore.
So what that it’s still under development now? In the real world, we know through experience that there’s no good reason not to future-proof this way.
Even if a border-radius disaster happened there’d still be no good reason unless paranoia is your driving motivation.
write the non-prefixed cross-browser version of the property first
– Damien
I see a lot of people do this and it annoys me. I don’t think it makes sense. Because you want the final, production ready, standard-compliant, non-vendor effect. It should be last so that, when the browser implements it fully, that is the one that has effect, not the testing version. Assuming the testing version stays around for some reason.
Visually I’d prefer to do the opposite order, too. But it just doesn’t communicate my intent.
hey Bruce, nice bit, and right as usual.
quick note, at the end of the post, you reference a comment from Rik, but the link doesn’t hold-up when it gets to your RSS feed…
the absolute path does:
http://www.brucelawson.co.uk/2010/cross-browser-future-proof-css-3/#comment-673631
cheers,
Atg
Yea I´ve been doing this for a while now too, I tend to add my css3 rules at the bottom of the selector with the vendor specs grouped in a comment so they´re easy to remove, if that day ever comes.
[…] Writing cross-browser, future-proof CSS 3 (a rant with the rant hat on) […]
[…] Suppose the site was made a while ago and used the experimental, pre-standardised code -webkit-border-radius and didn’t use the cross-browser future-proof method. […]
Is there any spec that defines cascading order for these vendor specific rules?
Will “-o-transform” overrides “transform” when transform rule supported? Or -o-transform will be deprecated when this happens?
I’m trying to find a spec which defines how this code will behave when “transform” starting to be supported:
#foo {
-o-transform: scale(2);
transform: scale(3);
}
[…] not using the full vendor-prefix stack (-moz-, -ms- , -o-, -webkit-, [no prefix]) resulting in code that is neither future-proof nor cross-browser […]
I tend to add my css3 rules at the bottom of the selector with the vendor specs grouped in a comment so they´re easy to remove,
Thank you for all information, I never entered in IE preview, it so nice :O!
This post I clarify many doubts, I will begin to apply this. : D
thank you very much.
Those standards have proven to be important in web development over the years and as you say using javascript to remove all that extra CSS away was a bad idea.
Assuming the spec doesn’t change of course, but that’s the peril of using pre-release code.