How to stop worrying about CSS vendor prefixes
There are a lot of ways to start using vendor-prefixed CSS features.
The Good
You could:
- Write them by hand using referring to something like CSS3 Please! or the Can I use site.
- Use Prefixr, which will do it for you.
- Use Prefix free, which will also do it for you but client-side.
- Use Sass mixins or Compass.
The important thing is that we have alternatives. Some are more powerful and take less time than others, but in the end they all accomplish the same by making our lives easier.
If you use any of the above methods I think it's safe to say that you may have already stopped worrying about vendor prefixes. And it's great. But...
The Bad?
Sometimes, however, that may not be enough.
Here are a couple of thoughts of my own about dealing with prefixes:
- Writing them by hand is, IMHO, tedious and error-prone. And so is having to check the Can I Use site everytime to get them right.
- Say, Firefox required a prefix for transitions up until version 15 and it still requires one for using Hyphenation. If I wanted to use both features and have only the latter one prefixed I wouldn't be able to do it with Compass or Prefixr as they are an all-or-nothing solution, i.e. either you prefix all properties/values or you don't, you don't get to choose.
- The Compass project iterates much slower than browsers nowadays so most of the times I end up creating my own mixins to output the correct prefixes.
- And even when you have custom mixins, it means you'll need to update them if a prefix is now required or one isn't anymore.
- Finally, the Prefix free client-side approach is not appealing to me. I'd rather have all my CSS compiled, compressed and ready to be deployed with no other side effects after the page is loaded.
The Awesome
Enter Autoprefixer, a tool that parses CSS and adds prefixed values when necessary according to the Can I Use site.
Why it's awesome
You can specify browser support via a configuration which can be done in different ways:
- Set support to specific browsers:
['ie 8', 'ie 7']
- Set support to only browsers that have certain market share:
['> 5%']
- Set support to the last
n
versions of browsers:['latest 2 versions']
You can use it with Ruby as a gem, as a Node.js package, as a standalone JavaScript library, as a Rework plugin or, and this one is my favorite, with Grunt via the grunt-autoprefixer plugin.
Demo
Let's actually create an example of what I'm talking about.
For this I'll assume you have Node.js installed, that you know how to setup a
project with Grunt and that you've used the grunt-contrib-watch
plugin.
First, go into your project folder and install the grunt-autoprefixer
plugin:
1 | npm install --save-dev grunt-autoprefixer |
Supposing we have a style.css
as:
1 2 3 | .test { display: flex; } |
Notice there are no signs of a vendor prefix anywhere, just the standard property and value.
Let's now create our Gruntfile.js
so that it watches over
the changes that we make to our style.css
file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | module.exports = function (grunt) { 'use strict'; grunt.initConfig({ autoprefixer: { options: { browsers: ['last 2 versions'] }, dist: { files: { 'style.css': 'style.css' } } }, watch: { styles: { files: ['style.css'], tasks: ['autoprefixer'] } } }); grunt.loadNpmTasks('grunt-autoprefixer'); grunt.loadNpmTasks('grunt-contrib-watch'); }; |
Check out the grunt-autoprefixer
plugin
repo
for further detail on the configuration.
But we're basically saying: "prefix considering only the last two versions of all major browsers".
Let's trigger a change so the grunt-contrib-watch
plugin comes
into action and executes the autoprefix
task.
The style.css
file should now be:
1 2 3 4 5 6 7 | .test { display: -webkit-box; display: -webkit-flex; display: -moz-box; display: -ms-flexbox; display: flex; } |
Which corresponds to, as of today, for flexbox:
- IE10 requiring the
-ms
prefix. IE9 not supporting the feature. - Firefox 22 not requiring a prefix. Firefox 21 requiring the
-moz
prefix. - Safari 6.0 requiring the
-webkit
prefix. Safari 5.1 also requiring it. - Opera 12.1 not requiring a prefix. Opera 12 not supporting the feature.
Now, let's try a different configuration and declare support only
for the latest version. Change line 7 of the Gruntfile.js
to:
1 | browsers: ['last 1 version']
|
We'll have to stop Grunt, re-run it and trigger a change.
The output this time will be:
1 2 3 4 5 6 | .test { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; } |
The only change between the two would be that there is no longer
a -moz
prefix because, as I stated before, Firefox 22 doesn't
require it.
Closing thoughts
Autoprefixr is configurable in a way that suits many needs. If I want to support the latest two versions of browsers and also IE9 (and IE8) I can.
It can integrate with Node.js and there's a Grunt plugin for it which makes it even easier to include in your build or development workflow.
But I think the absolute best would have to be that, because it uses Can I Use, it adapts to how the Web and Web Browsers are moving forward automatically and effortlessly.