Avatar of Chris Coyier
Chris Coyier on

I recently wrote Here’s the thing about “unused CSS” tools, where I tried to enumerate all the challenges any tool would have in finding truly “unused” CSS. The overarching idea is that CSS selectors match elements in the DOM, and those elements in the DOM come from all sorts of places: your static templates, dynamic templates based on server-side state, and of course, JavaScript, which can manipulate the DOM in any way at all, including pull things from APIs and third parties.

With all that at play, how can any tool give us a truly accurate picture of unused CSS, to the point that actually removing that CSS isn’t just as dangerous as leaving it alone?

So, I said:

And yet, I don’t think these tools are useless — they are just…tools. Their use can actually be a positive step toward better code. Their use says OK, I admit it, I’m a little afraid our CSS. You could use this tool to get a broad picture of what your unused CSS might be, then combine that with your own knowledge of your CSS code base to make more informed decisions.

I stand by that, and it’s worth pointing out some successful use cases.

Sarah Dayan just wrote How I dropped 250KB of dead CSS weight with PurgeCSS. She was using Tailwind CSS, an atomic CSS library that a lot of people have had success with.

In my case, not only did I load the entire Tailwind CSS library, but I also added several variants to some modules. That ended up making the final minified CSS file weight 259 KB (before GZip).

It’s a tenth of that when gzipped, but still, that’s a lot of CSS. Tailwind recommends using PurgeCSS, and that’s what Sarah did. PurgeCSS doesn’t handle any of things I mentioned, like state variations and JavaScript and whatnot, but it does look at any static files you’d like it to—both content and CSS—and do analysis from those. Even better, Sarah knew she had some third-party stuff going on, so handled that situation specifically:

PurgeCSS can’t detect that I need to keep selectors such as .ais-Highlight, because the components that use it only show up in the DOM at runtime.

So she split off some of that CSS and updated the configuration. Then…

With this new configuration, my final CSS file has gone from 259 KB to…9 KB!

I love it. Using the tool, being super aware of what is happening on your site, and making final choices for a combined win.

Sarah also mentions how this concept of unused CSS is related in spirit to the concept of unused JavaScript. In JavaScript, it’s referred to as tree shaking, and as Jeremy Wagner puts it:

Tree shaking is a form of dead code elimination.

I trust the tooling for tree shaking much more implicitly. These are tools written in JavaScript to look at JavaScript to discover JavaScript that isn’t used. It seems like the intersection of technology isn’t as wide when we’re talking about tree shaking. Still, there could be things like configured third parties that call public functions on your site, or event handlers directly on HTML elements. Those things seem a bit more rare to me these days, but that’s just my own experience bias.