One config to rule them all

Andrey Sitnik, Evil Martians

Browserslist

The company behind PostCSS and Autoprefixer

Check out my Twitter for the slides

Part 1. The problem.

Two most common Autoprefixer mistakes

.postcssrc
{
  "plugins": {
    "autoprefixer": {
      "browsers": [
        "last 2 Chrome versions",
        "last 2 Firefox versions",
        "last 2 Edge versions",
        "last 2 Safari versions"
      ]
    }
  }
}

Adds prefixes needed for specified browsers

/*
  "last 2 Chrome versions"
*/

.text {
  -webkit-user-select: none;
          user-select: none;
}
/*
  "last 2 Chrome versions"
  "last 2 Edge versions"
*/
.text {
  -webkit-user-select: none;
      -ms-user-select: none;
          user-select: none;
}

babel-preset-env is “Autoprefixer” for JS

.babelrc
{
  "presets": [
    ["@babel/preset-env", {
      "targets": {
        "browsers": [
          "last 2 Chrome versions",
          …
        ]
      }
    }]
  ]
}

Adds polyfills needed for specified browsers

/*
  "last 2 Chrome versions"
*/

const array = [1, 2, 3];
const [first, second] = array;
/*
  "last 2 Chrome versions"
  "last 2 Edge versions"
*/
const array = [1, 2, 3];
const first = array[0],
      second = array[1];

Two configs with the same list

"autoprefixer": {
  "browsers": [
    "last 2 Chrome versions",
    "last 2 Firefox versions",
    "last 2 Edge versions",
    "last 2 Safari versions"
  ]
}
["@babel/preset-env", {
  "targets": {
    "browsers": [
      "last 2 Chrome versions",
      "last 2 Firefox versions",
      "last 2 Edge versions",
      "last 2 Safari versions"
    ]
  }
}]

More tools, more configs with browsers

"autoprefixer": {
  "browsers": [
    "last 2 Chrome versions",
    "last 2 Firefox versions",
    "last 2 Edge versions",
    "last 2 Safari versions"
  ]
}
["@babel/preset-env", {
  "targets": {
    "browsers": [
      "last 2 Chrome versions",
      "last 2 Firefox versions",
      "last 2 Edge versions",
      "last 2 Safari versions"
    ]
  }
}]
"postcss-preset-env": {
  "browsers": [
    "last 2 Chrome versions",
    "last 2 Firefox versions",
    "last 2 Edge versions",
    "last 2 Safari versions"
  ]
}
"plugin/no-unsupported-browser-features": [true, {
  "browsers": [
    "last 2 Chrome versions",
    "last 2 Firefox versions",
    "last 2 Edge versions",
    "last 2 Safari versions"
  ]
}]

Part 2. The solution.

A single config for all tools

7

.browserslistrc

last 2 versions
> 1% in US
not dead # IE 10, BlackBerry, and Opera Mobile 12.1

* Only Babel 7 supports config file

Or package.json

{
  …
  "browserslist": [
    "last 2 versions",
    ">1% in US",
    "not dead"
  ]
}

* Only Babel 7 supports config file

Queries instead of exact versions

> 0.5%, > 0.5% in US, > 0.5% in alt-NA, > 0.5% in my stats
last 2 versions, last 2 Chrome versions
last 2 years, since 2016
Firefox ESR, Electron 1.4.5
not dead
extends @my-company/browserslist-config

Feature 1: Single config for all tools

Feature 2: A single development convention

— Do we still support IE 11?
— Check Browserslist config

Feature 3: Tools will think about browsers

  • Autoprefixer
  • babel-preset-env
  • postcss-cssnext
  • postcss-preset-env
  • eslint-plugin-compat
  • stylelint-no-unsupported-browser-features
  • postcss-normalize

Part 3. Who uses Browserslist?

The only recommended way for Autoprefixer

The only recommended way for Babel

@custom-media --mobile (width <= 800px);

@media (--mobile) {
 body {
   font-family: system-ui;
 }
}
@media (max-width: 800px) {
 body {
   font-family: system-ui,
                -apple-system,
                BlinkMacSystemFont, …
 }
}
/* last 3 versions */

audio, video {
  display: inline-block;
}

img {
  border-style: none;
}
/* last 2 versions */





img {
  border-style: none;
}

Part 4. The ecosystem.

const { matchesUA } = require('browserslist-useragent')

if (!matchesUA(request.headers['user-agent'])) {
  response.end(
    updateBrowserWarning + html
  )
} else {
  response.end(html)
}
> 0.5% in my stats
browserslist-stats.json
npx browserslist-ga

Part 4. The community.

Create React App

CSS Tricks

by Chris Coyier on CSS Tricks

Official public Browserslist configs

extends @ebay/browserslist-config
extends @wordpress/browserslist-config

Part 4. Best practices.

1. Do not specify browsers by name

last 2 Chrome versions
last 2 Firefox versions
last 2 Edge versions
last 2 Safari versions
last 2 versions

But it is OK for kiosks and Electron apps

last 1 Electron version

2. Don’t remove mobile browsers

defaults
not last 1 Android versions
not last 1 Samsung version
not last 1 iOS version
defaults

Mobile users visit desktop-only websites too

3. Don’t exclude browsers you don’t know

defaults
not Opera Mini all
not last 1 UCAndroid version
not last 1 QQAndroid version
not last 1 Baidu version
defaults

100M Opera Mini users in Africa

Opera Mini 2.66% > 1.86% Microfsoft Edge

* According Can I Use

Chinese browsers

UC Browser 7.51% > 3.85% Firefox + 2.71% Safari

* According Can I Use

The best queries

last 1 version
> 0.5% # or > 1% in my stats
not dead
defaults
# last 2 versions
# > 0.5%
# Firefox ESR
# not dead

Minimum

Perfect

4. Built-in CLI to check the result

npx browserslist
and_chr 64
and_ff 57
and_qq 1.2
and_uc 11.8
android 62
baidu 7.12
chrome 65
…

Coverage

npx browserslist --coverage
These browsers account
for 57% of all users
globally

Fixing 2 most common Autoprefixer mistakes

{
  "plugins": {
    "autoprefixer": {
      "browsers": [
        "last 2 Chrome versions",
        "last 2 Firefox versions",
        "last 2 Edge versions",
        "last 2 Safari versions"
      ]
    }
  }
}
{
  "plugins": {
    "autoprefixer": { }
  }
}
last 1 version
> 0.5% # or > 1% in my stats
not dead

5*. Do not support only popular browsers

> 1%
> 1%
last 1 version
not dead

Internet Explorer

Developers

The circle

Developers make sites for popular browsers

Users use browsers supported by wesbites

Now days

Twitter

Tweets about new awesome tools

Hedgehogs for every release

Subscribe

@browserslist

@evilmartians

@sitnikcode