Refining Our Autoprefixing

Posted by Tyler

Last night, I went to the CSS Layout Club Meetup. Natalya gave an excellent presentation about using CSS Grid. Jen followed up with a boatload of demos and bonus info about CSS Grid.

I don’t remember the exact context, but at one point Jen mentioned that the latest version of Autoprefixer stopped adding outdated CSS Grid syntax by default. Instead, it allows you to opt-in as needed with the grid setting.

That got me thinking about our usage of Autoprefixer on Limbo. Not only for CSS Grid, just in general. If you’re like me, you add Autoprefixer at the beginning of a project and never touch it again. I gave myself time this morning to have a look at it and refine how we’re using it.

Latest Autoprefixer

We use gulp-autoprefix for our prefixin’ needs. They released 4.0.0 in May to update to Autoprefixer 7.0.0. That version includes the grid option as well as a bunch of speed improvements. You should read about those in “Autoprefixer 7.0 and Browserlist 2.0”.

The only place we’re using CSS Grid today is in our Pattern Library. I’ve been trying it out there. Updating to Autoprefixer 7 only effected the CSS there. It removed occurrences of display: -ms-grid and -ms-grid-columns. A small change, but I’m happy to have it in place because we’ll use CSS Grid more in the future.

Configuration changes

Our Autoprefixer configuration has been the same since day one. In our Gulp file we use:

autoprefixer({ browsers: ["last 2 version"] })

As mentioned, I’ve never paid much attention to this or even looked to see what prefixes ended up in the stylesheet. Realizing I didn’t know those details made me nervous this morning.

Moving browserslist config

The first change I made was a code shuffle. In the Autoprefixer 7 post mentioned above, they made a new recommendation:

We recommend specifying target browsers in package.json only.

That sounds good to me. I updated our Gulp file:

autoprefixer()

and made a new entry in our package.json:

"browserslist": [
  "last 2 version"
]

This didn’t change the output, only changed the location we configure our target browsers.

Flexbox

Flexbox is my go-to for layout on Limbo and everywhere. By default, Autoprefixer adds the “2009” version of Flexbox. I’m not 100% sure what browsers need that syntax, but I’m making an assumption it’s a trivial amount of our traffic. And without Flexbox, all the content is still available. I updated the Gulp config with:

autoprefixer({
  flexbox: "no-2009"
})

If we find out that’s causing trouble for people, it’s easy enough to put back in place.

Browsers to prefix

In our browsers config we specified “last 2 version”. I took a look at the compiled stylesheet and didn’t like what I saw. It was littered with prefixes for properties with wide support like box-sizing, box-shadow, transition, and transform. There were 55 occurrences of -webkit-box-shadow alone.

I needed to change the browserslist query to get those unneeded prefixes out of there. Even after reading the documentation about queries, they’re a bit of a mystery to me. I needed a different picture of the problem. I needed to visualize which browsers would be included in the to-prefix list for each query.

Turns out there’s a tool for that exact thing. http://browserl.ist lets you provide a query and see the list of browsers it will include. That helped me reference Can I Use to see which browsers might be causing the unneeded prefixes.

To get a visual on what the browserslist queries would result in there’s another great tool, http://autoprefixer.github.io/. You plug in CSS and queries to see the resulting Autoprefixed CSS.

Those tools gave me the clarity to change the browserslist query until it removed all the prefixes I didn’t want. Here’s what I ended up with:

"browserslist": [
  ">= 7.7%"
]

Now, that’s pretty durn specific. It says; “only add prefixes to help browsers with greater than or equal to 7.7% of global usage.” How did I land at that number?

I did not want to prefix:

  • box-sizing
  • box-shadow
  • transition
  • transform

Using the query “>= 1%” removes prefixes for the first three properties. Those have wide support. transform was tougher. According to Can I Use data, UC Browser 11.4 for Android has 7.65% global usage. It also requires the -webkit prefix for 2D and 3D CSS transforms.

With that data, I chose “>=7.7%” to say; “don’t worry about prefixing properties in UC Browser 11.4.” That may end up being brittle. If UC Browser usage goes up, our query will need to follow. But, it works for now. That’s also not to say we don’t care about our users with that browser. It’s us saying that the core experience will still be 100% in place without CSS prefixes for transform.

Remaining prefixes

We’re down to only two prefixed properties in our stylesheet:

  • Eight uses of -webkit-appearance,
  • and two uses of text-size-adjust. One with -webkit and one with -ms.

text-size-adjust doesn’t get Autoprefixed. It’s included in our normalize.css.

That means we’re down to appearance as the single property that Autoprefixer handles. I’m OK with that. Having Autoprefixer in our build process doesn’t add any noticeable slow down so it doesn’t seem worth it to remove it.

What improved?

This work didn’t move the performance needle. The non-gzipped file size of our style sheet dropped from 117K to 109K. A savings of ~8K. So, nothing to speak of in that department.

What it did improve was my understanding of what Autoprefixer was adding to our stylesheet and why it did so. That’s important for me. It’s too easy to hand this stuff over to the computer and never give it a second look.

The knowledge gained was 100% worth the small time investment.

Tyler Gaw

Tyler is the Co-Founder of Limbo. He works on the Product Design and designs and builds the front-end.

See all Tyler’s posts