The following is a guest post by Andrey Sitnik, the creator of the Autoprefixer tool, a “postprocessor” for handling vendor prefixes in CSS. Why use this instead of your preprocessor or another tool? Many reasons. Andrey will explain.
Autoprefixer parses CSS files and adds vendor prefixes to CSS rules using the Can I Use database to determine which prefixes are needed.
All you have to do is add it to your asset building tool (Grunt, for instance) and you can totally forget about CSS vendor prefixes. Just write regular CSS according to the latest W3C specifications without any prefixes. Like this:
a {
transition: transform 1s
}
Autoprefixer uses a database with current browser popularity and properties support to apply prefixes for you:
a {
-webkit-transition: -webkit-transform 1s;
transition: -ms-transform 1s;
transition: transform 1s
}
The Problem
We can, of course, write vendor CSS prefixes by hand, but it can be tedious and error-prone.
We can use services like Prefixr and text editor plugins, but it is still exhausting to work with big blocks of repeating code.
We can use mixin libraries with preproccesors like Compass for Sass or nib for Stylus. They solve a lot of problems, but create other problems instead. They force us to use a new syntax. They iterate much slower than modern browsers do, so a stable release can have a lot of unnecessary prefixes, and sometimes we need to create our own mixins.
And Compass does not really hide prefixes from you since you still need to decide on a lot of questions, for example: Do I need to write a mixin for border-radius
? Do I need to split arguments for +transition
by comma?
Lea Verou’s -prefix-free came closest to solving this problem, but using client side libraries is not such a good idea when you take end-user perfomance into account. To avoid doing the same job again and again, it is better to build CSS once: during asset building or project deployment.
Under the Hood
Instead of being a preprocessor – such as Sass and Stylus – Autoprefixer is a postprocessor. It doesn’t use any specific syntax and works with common CSS. Autoprefixer can be easily integrated with Sass and Stylus, since it runs after CSS is already compiled.
Autoprefixer is based on Rework, a framework for writing your own CSS postproccesors. Rework parses CSS to useful JavaScript structure and exports it back to CSS after your manipulations.
Each version of Autoprefixer contains a copy of latest Can I Use data:
- List of current browsers and their popularity.
- List of prefixes required for new CSS properties, values and selectors.
By default, Autoprefixer will support 2 latest versions of major browsers, much like Google does. But you can choose, what browsers are supported in your project, by name (like “ff 21”) or by pattern:
- Last 2 version of each major browsers using “last 2 versions”.
- With more that 1 % of global usage statistics using “> 1%”.
- Only newer versions by “ff > 20” or “ff >= 20”.
Then Autoprefixer calculates which prefixes are required and which are outdated.
When Autoprefixer adds prefixes to your CSS, it doesn’t forget about fixing syntax differences. This way, CSS is produced according to the latest W3C specs:
a {
background: linear-gradient(to top, black, white);
display: flex
}
::placeholder {
color: #ccc
}
compiles to:
a {
background: -webkit-linear-gradient(bottom, black, white);
background: linear-gradient(to top, black, white);
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex
}
:-ms-input-placeholder {
color: #ccc
}
::-moz-placeholder {
color: #ccc
}
::-webkit-input-placeholder {
color: #ccc
}
::placeholder {
color: #ccc
}
Autoprefixer cleans outdated prefixes as well (from legacy code or CSS libraries like Bootstrap), so the following code:
a {
-webkit-border-radius: 5px;
border-radius: 5px
}
compiles to:
a {
border-radius: 5px
}
So after Autoprefixer, CSS will contain only actual vendor prefixes. After Fotorama switched from Compass to Autoprefixer, the CSS file size decreased by almost 20%.
Demo
If you still don’t use any kind of tool to automate the building of your assets, be sure to check out Grunt. I highly recommend to start using build tools. This can open you a whole new world of “sugar” syntaxes, time-saving mixin libraries and useful image processing tools. All of developers’ productivity methods to save a lot of nerves and time (the freedom to choose languages, code re-use, the ability to use third-party libraries) are available now for front-end programmers.
Let’s create a project directory and write simple CSS in style.css
:
a { }
For this example, we will use Grunt. First, we will need to install grunt-autoprefixer
using npm:
npm install grunt-cli grunt-contrib-watch grunt-autoprefixer
Then we should create Gruntfile.js
and enable Autoprefixer:
module.exports = function (grunt) {
grunt.initConfig({
autoprefixer: {
dist: {
files: {
'build/style.css': 'style.css'
}
}
},
watch: {
styles: {
files: ['style.css'],
tasks: ['autoprefixer']
}
}
});
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-watch');
};
This config enables the compilation of style.css
to build/style.css
using Autoprefixer. Also we will use grunt-contrib-watch
to recompile build/style.css
every time style.css
changes.
Let’s start Grunt’s Watch:
./node_modules/.bin/grunt watch
Now, we’ll add a CSS3 expression to style.css
and save the file:
a {
width: calc(50% - 2em)
}
The magic has just happened and now we have a build/style.css
file. Grunt detected the change in style.css
and launched the Autoprefixer task. Autoprefixer did find the calc()
value unit, that needs a vendor prefix for Safari 6.
a {
width: -webkit-calc(50% - 2em);
width: calc(50% - 2em)
}
Now we’ll add a little bit more complicated CSS3 to style.css
and save the file:
a {
width: calc(50% - 2em);
transition: transform 1s
}
Autoprefixer already knows that Chrome, Safari 6 and Opera 15 need prefixes for transition
and transform
. But IE 9 also needs a prefix for transform
, which we used as value in transition
.
a {
width: -webkit-calc(1% + 1em);
width: calc(1% + 1em);
-webkit-transition: -webkit-transform 1s;
transition: -ms-transform 1s;
transition: transform 1s
}
Autoprefixer is designed to perform all the dirty work for you. It will check the Can I Use database, write all the prefixes needed and it does understand the difference between specifications as well. Welcome to the future of CSS3 — no more vendor prefixes!
What Next?
- Autoprefixer supports Ruby on Rails, Middleman, Mincer, Grunt, Sublime Text. Learn more about how to use it with your environment in the documentation.
- If your environment doesn’t support Autoprefixer yet, please, report it and I’ll try to help.
- Follow @autoprefixer for info on updates and new features.
This is great. I always forget at least one vendor CSS prefixe so this would be very useful to have.
Would it also add prefixes for older IE version like Compass does http://compass-style.org/reference/compass/css3/images/#mixin-filter-gradient
I think mixins is the ‘right way’ in such cases, just write several mixins and place them in a lib for yourself.
IE hacks isn’t best idea for everyone, because old IEs use on old machines and this hacks is very slow. For example, I prefer graceful degradation. So mixins is betters for this task. Or you can write another postprocessor (it’s really very easy by Rework) to add this hacks.
I love Autoprefixer. Been using it for a few months now on small projects (I use Sass on Compass on big ones) and it’s such a time saver! I use the Sublime Text 2 Plugin but I had no idea it’s also available as a Grunt plugin!
Great post, thanks for the tips :)
Thank you Sara Soueidan for your feedback about your experience with Autoprefixer. Matter of fact I was searching for a user experience based review, not simply a promotonial one. Reliable timesavers are also very welcome in my house.
Thanks for helping me making up my mind.
Nice! I love the command-control-x shortcut in Sublime Text 2 myself!
i just told myself “i’m using sass/compass. good enough. got a good workflow. no new stuff needed at the moment.”
..but then i saw that there was a plugin for sublime text.
“ok. take my money”.
If you use Sass and Compass, try to use Autoprefixer with sme build tools (Rails, Grunt). It’s difficult to read and edit your prefixed CSS after Sublime Text plugin.
this definitly confirms again browsers creators don’t learn from the past, it’s messed up that we always have to ‘fix’ the browser with tricky tools, hack around to get closer to (there own) standards (which are well-defined atm). First conditional comments, then css-hacks, now css-compilers and css-fixers that plug into the compilers too. Unbelievable, browsers will always be “beta”-products.
Great tool anyways.
Mark, if I remember correctly, browsers use the vendor prefix because the particular css property is essentially in a ‘beta’ form for that browser (version), and once they feel it has been implemented correctly they allow the browser to recognize the unprefixed syntax. Every now and then you’ll find you no longer need the prefixing, such as “border-radius”, for the latest versions.
I love this. I will never worry about vendor prefixes again.
Is it possible to integrate it into a Compass (Foundation) workflow so I don’t have to run Compass and Grunt? I feel like I’m close, trying to use autoprefixer-rails and Compass’ ‘on_stylesheet_saved’ in my config.rb, but I have been unsuccessful so far.
Maybe it will be better to run Sass compiling in Middleman (it already has Autoprefixer support). Maybe we can add Autoprefixer to Compass foundation, but it will be a little hacky way :(.
BTW, Middleman (and other build tools, like Scout) is much more powerful, that Compass.
I try to add solution for Compass to README.md soon.
Done. Autoprefixer README now has section about integration with Compass:
require ‘autoprefixer-rails’
on_stylesheet_saved do |file|
css = File.read(file)
File.open(file, ‘w’) { |io| io << AutoprefixerRails.compile(css) }
end
https://github.com/ai/autoprefixer#javascript
“You can use Autoprefixer in the browser”
Could someone explain how you would do this? Load your CSS into a browser window and run as a bookmarklet? Run from a webpage that contains your CSS?
I do a lot of projects where my workflow dictates that I modify a CSS file, then upload to the server.
Autoprefixer now doesn’t have end-user tools to work in browser. If you add standalone JS it just create
window.autoprefixer.compile()
function and you need to call it by hand :(.Try to use Autoprefixer plugin for Sublime Text or try to add Grunt (or something like this) to your workflow (because there are a lot of cool tools).
Thanks Andrey. I really appreciate you putting together this tool and releasing it to the public for free. I do wish there were a more direct way to use it than installing multiple command-line tools or switching to another text editor.
Have you considered releasing it as a web service as Prefixr has done? http://prefixr.com
Unfortunately, I didn’t like idea with web services (and text editor plugin). You process your CSS only once, then you forget about your files and they become to outdated. Prefixes will be outdates only after few month. If new browsers will start to support property, you willn’t add new prefixes.
If you use build tool, you just need to update your libraries (like only one command
bundle update
ornpm update
) and you can be sure that all your styles is actual.But you can create this web services if you want (easy way to get community respect and popularity, like other Autoprefixer plugins developers).
Is there a way to make it work on CodeKit?
Not now, but you can support this issue https://github.com/bdkjones/CodeKit/issues/653
As Bryan says, it will be added.
Has anybody already tried this one ? http://leaverou.github.io/prefixfree/
Lea’s -prefix-free is cool tool and good variant if you can use asstes build tool. But it works only in browser and very bad for client perfomance, because it will process CSS in end-user browsers, instead of process CSS once on deploy.
Very nice tool Andrey. nice job.
About prefixfree… I already used it in a few projects and didn’t notice any performance issues. Is there any chart or benchmark that shows this “bad client performance”?
Perfomance issue is in CSS. User can’t immediately see your page, because page CSS will be ready only after JS work. But, unfortunately, there is not benchmarks (it is not so easy to benchmark CSS loading process).
For stuff like legacy linear gradients and radial gradients with certain degrees that drastically differ based in the same values, does Autopreixer that that into account?
Yeap, Autoprefixer can do math with digits and very flexibly change syntax.
But don’t belive me and check tests :) from → to
Hi Andrey,
this seems to be the tool which i was searching for a long time. is there an easy tutorial how to install & start this on mac os – i just read the readme on github but it i have no idea how to start, with this stuff of commandlines and so on …
You need to install Homebrew, then install Node.js and npm. Try this good How To on Changelog.
With npm you can install Grunt and Autoprefixer by How To from this CSS Tricks article.
Its interesting that flexbox was used in the example – how would this work mixing old and new versions of flexbox, wouldn’t it remove outdated, but relied upon prefixes?
Autoprefixer will remove outdated flexbox properties (but now it has issue, that
-webkit-
2009 spec prefix is not outdated for Autoprefixer).Also Autoprefixer willn’t double your prefixes.
I understand your question right? :)
I’ve not really used flexbox but my question is based around the idea of using a mixture of both old and new spec flexbox as posted here https://css-tricks.com/using-flexbox/
I’m not trying to put a downer on what is clearly an awesome idea, just curious!
Yeap, Autoprefixer fix specs for you. You write CSS only by latest W3C spec without prefixes and forget about other flexbox specs. Autoprefixer will rewrite properties for all old specs.
Wow. that ranks pretty highly on the awesome scale!
Can’t we just use SCSS and Bourbon.io?
That would require you to update your mixins every time a prefix changes
Because, you need to always think, where you need to use mixin and where you doesn’t. Also Bourbon development cyrcle is much slower, that browsers updates. See all points about Compass in article, they same with Bourbon.
Nice!
thank you Chris.
Oh!excuse me…
thank you Andrey :)
Never seen an author follow his post like this and reply all the queries. Your CSS Postprocessor Tool certainly looks cool. I’d definitely try and follow its development closely.
Just want to say, Thank you Andrey for making it available for us to use.
Great article, but there’s something I’d recommend changing. When you install grunt (
npm install grunt-cli ...
), you don’t install it globally.Generally speaking, it’s better to install Grunt globally (using
npm install -g grunt-cli
instead), because it prevents you from having to reference your local project’s install of Grunt (as you do here, with./node_modules/.bin/grunt watch
).Good article, glad to see the Grunt ecosystem expanding to include tools to make our lives even easier. Thanks Andrey.
And what you will do if some project will require one version of npm package, and another project will require another version?
In Ruby world we use Bundler, which lock libs for each project. So I try to use this way in node too. I store all project dependencies inside project dir (but not in git, of cource).
But your way is possible too :).
Andrey,
grunt-cli
should be installed globally, it’s just a CLI tool, andgrunt
is installed locally as a peer dependency.Has anybody a working example of a Gruntfile.js with autoprefixer and livereload?
I don’t get them to work together. Autoprefixer just don’t gets started when livereload is active.
My Gruntfile.js: https://gist.github.com/sdvg/f0a881cfc0ae9e412e01
I didn’t build this gruntfile from scratch, so I don’t necessarily understand everything about it (I borrowed and adapted from an already-working file), but autoprefixer seems to work for me here. I’m using grunt-regarde to watch for changes, which may be a difference. Here’s the gruntfile (coffeescript syntax):
https://github.com/byuweb/byu-responsive-dev/blob/eb4a269cbcd2df8d982b39db8bbd34b6ebee75e9/Gruntfile.coffee
Awesome work. I’m impressed with the tool, and also with the variety of implementations available for different environments.
I’m using grunt to build my CSS, compiling from .scss files, using a fair amount of Compass in the SASS. I had a couple of questions:
Compressed output – The post-processed CSS files actually get a little bigger after running through autoprefixer, because I’m using compressed output from SASS. Is there a way to enable compressed output from autoprefixer?
Source maps – This seems a little more difficult. I’ve got SASS outputting source maps along with CSS so that I can see the .scss sources in Chrome dev tools (rather than seeing just the css file as source). It’s incredibly helpful. Running through autoprefixer after compiling the sass totally messes up the source mapping. I can’t think of any way to get around that. Any thoughts?
Sass is not a best way to compress CSS. Try csso: https://github.com/t32k/grunt-csso
Source Map is very important, but it need a lot of changes in parser. Please, support this issue: https://github.com/visionmedia/rework/issues/109
I’ve had very mixed success with getting Source maps to work. I found a specific version of sass and compass in the end that seemed to work, then after 24 hours the latest Chrome Canary update made things extremely unstable so I just gave up with it. Hopefully source maps will be added to a non beta version of sass soon.
I will look into autoprefixer though, thanks Andrey. Grunt seems pretty nice too, but then I do love not having to use the command line with compass.app.
@Patrick, I agree that source maps can be a pain. I’ve also been using a pre-release of SASS for it, but have been able to stick with regular Chrome rather than Canary. I also hope that SASS source maps get into a full release soon. Until then, the convenience of source maps is enough for me to put up with a little bit of pain.
@Patrick: source maps support for SASS already ARE in Chrome stable and have been for two months!
Compass/Sass don’t force you to change transition syntax to using commas, that’s the beauty of it over Less. Instead of ‘transition: width 1s ease’ you write ‘@include transition(width 1s ease)’.
Please, update the article correcting the mistake.
It doesn’t say you have to, it suggests that you have to think about whether you have to or not instead of not having to think about it.
My idea is, that before you was need commas and other mixins need commas. So you need to think, does I need commas in
transition
or not? I saw a lot of wrong Sass code with commas.On your corses some developer ask, why their Sass code was broken after Compass update or why their transition doesn’t work.
That’s not true, you don’t have to think about commas in any mixin adding prefixes. All mixins adding prefixes are used in exactly the same way: instead of:
property: some rules, some other rules;
you write:
@include property(some rules, some other rules);
You just add @include and use brackets instead of a colon. But the value is written symbol-by-symbol in exactly the same way. Anyone doing it differently does it wrong.
I agree Autoprefixer lets you not think even about it but that doesn’t change the fact that you described Compass usage as way more difficult than it really is.
I get your point. But I’m a compass user and I sometimes think about it. It was phrased that way in the article, so I won’t be changing it.
Lovely tool Andrey. Immediately added to my grunt workflow boilerplate.
Thanks mate!
Andrey this is absolutely beautiful. We’re going to work on implementing this in Jeet asap. Kudos.
We’ve added this to Jeet by default, and Jeff Escalante has turned it into a great standalone Stylus plugin: https://github.com/jenius/autoprefixer-stylus
Now you can use it with Stylus like so and efficiently replace 90% of preprocessor library functionality:
npm install -g autoprefixer-stylus
stylus -u autoprefixer-stylus -w