Plenty of caching plugins have an option called “Remove Unused CSS.” Turn it on and it scans your pages, deletes every selector no element uses, and sends the browser a slimmed-down stylesheet.

Most of the time that works well. The problem is that it decides statically.

Three things it can’t read

First, classes added in the page builder’s back end. A name typed into an element’s “extra class” field doesn’t appear anywhere in the templates, so the scanner assumes nobody uses it.

Second, design tokens declared only on :root. You define the variables now and plan to use them later, and nothing references them yet. To the scanner, that’s dead code.

Third, classes that scripts attach at runtime. The scan is done before any of that happens.

Why it’s hard to spot

Every piece of evidence we could get our hands on said things were fine.

The file on the server had the declaration. So did the combined file. In DevTools, the file loaded with a 200.

The one thing that turned out to tell the truth was getComputedStyle(), which reports the value the browser actually ended up using. Our first two checks both came back all green because we took “the file on the server has it” as proof. Now we verify with getComputedStyle() every time.

What we do now

Declarations that would get stripped are injected by the plugin as inline styles instead. Inline styles don’t go through the removal step.

WordPress lets you declare dependencies between stylesheets so that A always loads after B. We used to think a dependency meant we were covered. It guarantees the order. It doesn’t guarantee the file gets loaded at all.