Autoprefixer 7.0 has been released! Learn about the key features—and why the addition of Browserslist 2.0 is the largest change.
Autoprefixer was released four years ago to create a universal tool for dealing with browser-specific CSS prefixes. It was based on the work I was doing with Evil Martians as a frontend developer. In May 2017, Autoprefixer hit its next major release—7.0 “Coelestem adspicit lucem”.
This new version uses the brand new PostCSS 6.0 with lower memory usage. Dmitry Semigradsky has entirely rewritten Autoprefixer from CoffeeScript to Babel. Additionally, Node 0.12 is not supported anymore, and Grid Layout prefixes are disabled by default.
However, the most significant change in Autoprefixer 7.0 is the new Browserslist 2.0.
What is Browserslist?
With Autoprefixer, you can specify which browser versions you wish to target in your application; Autoprefixer will only add the CSS prefixes required for selected browsers.
autoprefixer({ browsers })
From the very start, we’ve recommended against freezing browser versions with a specific number. Browsers update way too often these days, and it’s easy to forget to update the supported versions in your config.
That’s why Autoprefixer has supported specific queries to select browsers according to the Can I Use browser usage database since the first version. For example, > 1%
will select all browser versions with more than 1% in global usage (according to statistics).
autoprefixer({ browsers: 'last 2 versions, > 1%' })
However, the need to have a list of targeted browsers is not unique to Autoprefixer. Modern frontend development implicates the use of linters and many other tools, so it may be a good practice to move the “supported browsers” list to a standard config file to have this specified in a single place.
To make this vision real, two years ago, with Autoprefixer 5.0, we moved our browser queries parser to a separate library called Browserslist. It reads browser selection queries from package.json
and could be used in many different tools:
"browserslist": [
"last 2 versions",
">1%"
]
Who uses Browserslist
Autoprefixer. Let’s start with the obvious: Autoprefixer loads a list of supported browsers from the browserslist
key in package.json
. You don’t need to do anything else; Autoprefixer will automatically find and load the config.
babel-preset-env is the “Autoprefixer for JavaScript”. It won’t compile ES2015+ syntax if it already knows all your target browsers support it natively.
"babel": {
"presets": [
[
"env",
{
"targets": {
"browsers": "last 2 version",
"node": 4
},
"loose": true
}
]
]
}
Unfortunately, right now, babel-preset-env
will not work with the Browserslist config out of the box—however, this will be fixed in the next major release.
eslint-plugin-compat is a plugin for ESLint that warns when not all targeted browsers can support your JavaScript code. It supports Browserslist config out of the box; it takes the list of target browser versions and checks that your code uses JavaScript APIs supported by all of the specified browsers.
stylelint-no-unsupported-browser-features works like eslint-plugin-compat
, but for CSS. Stylelint is outstanding and the most popular CSS linter. This Stylelint plugin makes sure that all targeted browsers support all used CSS properties. It supports Browserslist config out of the box as well.
postcss-normalize only includes the necessary parts of normalize.css, based on your list of supported browsers.
How to use Browserslist
Browserslist is a JavaScript library. If your frontend tool of choice includes support for Browserslist, it will look for browser version-specifying queries in the following places, going from first to last:
- Tool options. Think the
browsers
option in Autoprefixer. - The
BROWSERSLIST
environment variable. - The
browserslist
or.browserslistrc
config file. - The
browserslist
key inpackage.json
.
Browserslist will look for config files and package.json
recursively in directories from bottom to the top. If you have a components/header/header.css
file, Browserslist will check components/header/
for configs first, followed by components/
, and then the root of the project.
We recommend only specifying target browsers in package.json
. Even if Autoprefixer is the only tool you’re going to use, don’t specify your target browsers in Autoprefixer’s browsers
option.
Many tools have Autoprefixer included (postcss-cssnext
, old webpack versions). If you use the browser
option, “other” Autoprefixers will not see your browser requirements. As a result, they could remove the prefixes previously added by Autoprefixer.
If you set browser requirements in the Browserslist config instead, all your tools can use the same config.
Autoprefixer 7
Autoprefixer has already been using Browserslist for two years. Now, after these years of success, we’re finally introducing Browserslist 2.0 with the following important changes:
- Reduced
node_modules
size. - Better performance with filesystem caching.
- Changes in the
last n versions
query.
Reduced node_modules
size
In the JavaScript community, it’s natural to complain about the size of the node_modules
directory. Having a separate copy of the entire development environment specific for a project is a great feature, but not all npm packages care about their size in a way that’s respectful to the user.
caniuse-db
is one of these “offending” packages—it was designed primarily for the “Can I Use” website and it needs (and has) lots of data that’s irrelevant for Autoprefixer and Browserslist. As a result, caniuse-db
is an enormous 7 MB!
Ben Briggs, one of the key developers in the PostCSS community, came up with a solution—he created caniuse-lite
. A script takes the caniuse-db
package, removes unneeded data, compresses the rest, and automatically releases a new caniuse-lite
package following every caniuse-db
release.
As a result, the size of caniuse-lite
is only 1 MB—7 times less! Accordingly, Autoprefixer 7 and Browserslist 2 depend on caniuse-lite
instead of caniuse-db
.
Better performance
Unfortunately, many significant tools use synchronous APIs; hence, Browserslist must work with synchronous APIs as well. However, many file system operations can be required to find a config file.
Luckily for us, Finnish developer Aarni Koskela decided to tackle Browserlist bottlenecks—to great success.
He found many problematic places and we’ve fixed some of them in previous patch releases. However, we’ve been waiting for a major release to ship his primary improvement: Browserslist 2 ships with caching for file system operations.
As a result, Browserslist is now 6 times faster; this could make an average Gulp config 5 to 10% faster.
However, please note that most tools do not empty the Browserslist cache by themselves, so you need to restart your webpack development server to see changes. Fortunately, Browserslist config changes are relatively rare, so it’s a reasonable trade-off.
Changes in last n versions
for a better Web
From the very beginning, Autoprefixer’s last 2 versions
selected 2 last browser versions, but not from all browsers—just the most popular ones. As it turns out, that was a mistake.
There are no “main” browsers in the real world. For instance, the online market is enormous in China, and there are a lot of popular local browsers in China. We cannot just ignore local browsers—The Web should be accessible to everyone.
In fact, Autoprefixer itself was created to stop browser differentiation (like using -webkit-
-only prefixes for mobile browsers).
So, this is why Autoprefixer 7 and Browserslist 2 last 2 version
will select the 2 last versions of all browsers.
Don’t worry about the size—gzip
compresses prefixes quite well, so most likely, you will not see any differences in size. See our discussion with Eric Bidelman from Google.
To summarize,
- Move your browsers list from Autoprefixer’s
browsers
option to thebrowserslist
key inpackage.json
. - Update to Autoprefixer 7 to reduce the size of
node_modules
and make it faster.
Enjoy the release!