If you’re interested in translating or adapting this post, pleaseemail us first.
Autoprefixer 7.0 is 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 to deal with browser-specific CSS prefixes, based on the work I was doing in Evil Martians as a frontend developer. In May 2017, Autoprefixer hits its next major release—7.0 “Coelestem adspicit lucem”.
The new version uses brand new PostCSS 6.0 with lower memory usage. Dmitry Semigradsky rewrote Autoprefixer entirely from CoffeeScript to Babel. 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 do you wish to target in your application. This way, Autoprefixer will only add the CSS prefixes required for selected browsers.
autoprefixer({ browsers })
From the very start, we have recommended against freezing browser versions with a specific number. Browsers update way too often these days, so it is easy to forget to update supported versions in your config.
That is why since the first version Autoprefixer supports specific queries to select browsers according to the Can I Use browser usage database. 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 it specified in a single place.
To make this vision real, two years ago, with Autoprefixer 5.0, we have 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
Browserslist users
Autoprefixer. Start with the obvious: Autoprefixer loads the list of supported browsers from the browserslist
key in package.json
. You don’t need to do anything else—Autoprefixer will find and load the config automatically.
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, it will be fixed in the next major release.
eslint-plugin-compat is a plugin for ESLint to warn you 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 an 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
browsers
option in Autoprefixer. -
BROWSERSLIST
environment variable. -
browserslist
or.browserslistrc
config file. -
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 specifying target browsers in package.json
only. Even if Autoprefixer is the only tool you are going to use, don’t specify them 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 prefixes previously added by Autoprefixer.
If you set browser requirements in Browserslist config instead, all tools could use the same config.
Autoprefixer 7
Autoprefixer has been using Browserslist for two years already. Now, after two successful years, we are 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
Vladislav Kozulya’s joke based on The mysterious boundary article by Andrew Grant
In the JavaScript community, it is natural to complain about the node_modules
directory size. To have a separate copy of the whole development environment specific for a project is a great feature—but not all npm packages care about their size in a way that is respectful to the user.
caniuse-db
is one of those “offending” packages—it was designed primarily for Can I Use website needs and has lots of data that is irrelevant for Autoprefixer and Browserslist needs. As a result, caniuse-db
is enormous—7 MB!
Ben Briggs, one of the key developers in 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, caniuse-lite
size is only 1 MB—7 times less! Autoprefixer 7 and Browserslist 2 depend on caniuse-lite
instead of caniuse-db
.
Better performance
Unfortunately, many significant tools use synchronous API; hence, Browserslist must work with synchronous API as well. However, many file system operations could be required to find a config file.
Luckily for us, Aarni Koskela from Finland went to war with Browserlist bottlenecks—and he has won.
GitHub party
He has found many problematic places; we have fixed some of them in previous patch releases. However, we have waited for a major release to ship his main improvement.
Browserslist 2 ships with caching for file system operations.
As a result, Browserslist is now 6 times faster. That could make an average Gulp config 5 to 10% faster.
However, please note that most tools do not empty 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 is a reasonable trade-off.
Browserslist 2 caching benchmark
Changes in last n versions
for the 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, China online market is enormous, 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 browsers differentiation (like using -webkit-
-only prefixes for mobile browsers).
So that is why Autoprefixer 7 and Browserslist 2 last 2 version
will select 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 tobrowserslist
key inpackage.json
. - Update to Autoprefixer 7 to reduce
node_modules
size and make it faster.
Enjoy the release!