How to Identify and Remove Unused CSS
Most websites ship 70-90% unused CSS. Learn how to find dead CSS, safely remove it, and prevent it from accumulating again.
Studies consistently show that the average website ships 70-90% unused CSS. On a typical site with 200KB of CSS, that's 140-180KB of styles the browser downloads, parses, and holds in memory for absolutely nothing.
Why Unused CSS Matters
Render Blocking
CSS is render-blocking by default. The browser won't paint anything until ALL CSS is downloaded and parsed. More CSS = longer time to first paint.
Parse Time
The browser must parse every CSS rule to build the CSSOM (CSS Object Model). More rules = longer parsing = delayed rendering.
Memory
Every CSS rule stays in memory for the page's lifetime. On memory-constrained mobile devices, this matters.
Specificity Confusion
Dead CSS rules can accidentally match new elements, causing unexpected styling. This creates maintenance headaches.
Finding Unused CSS
Chrome DevTools Coverage
- Open DevTools (F12)
- Press Ctrl+Shift+P → type "coverage"
- Click "Start instrumenting coverage and reload page"
- Interact with the page (open menus, scroll, click tabs)
- Check the CSS files — red bars show unused bytes
PurgeCSS (Automated)
PurgeCSS analyzes your HTML/JS and removes CSS rules that don't match any selectors:
npx purgecss --css styles.css --content index.html --output cleaned.css
UnCSS
Similar to PurgeCSS but loads the page in a headless browser to detect dynamically generated classes:
npx uncss https://yoursite.com > cleaned.css
Safely Removing Unused CSS
Step 1: Audit
Use Coverage tab to identify which CSS files have the most waste.
Step 2: Understand Dynamic Usage
Some CSS appears "unused" on initial load but is needed for:
- Hover states
- Modal dialogs
- Dropdown menus
- JavaScript-triggered states
- Other pages (if using a shared stylesheet)
Step 3: Use PurgeCSS with Safelist
// postcss.config.js
module.exports = {
plugins: [
require('@fullhuman/postcss-purgecss')({
content: ['./src/**/*.{html,js,jsx,tsx}'],
safelist: {
standard: ['active', 'open', 'visible', 'modal-open'],
deep: [/^data-/],
greedy: [/toast/, /tooltip/],
},
}),
],
};
Step 4: Test Thoroughly
After removing CSS:
- Check all pages visually
- Test interactive states (hover, focus, active)
- Open all modals, dropdowns, accordions
- Test on mobile and desktop
- Run visual regression tests if available
Prevention Strategies
1. Component-Scoped CSS
Use CSS Modules, styled-components, or Tailwind CSS — styles are scoped to components and automatically removed when the component is deleted:
// CSS Modules — styles only apply to this component
import styles from './Button.module.css';
<button className={styles.primary}>Click</button>
2. Tailwind CSS with JIT
Tailwind's JIT compiler only generates the CSS classes you actually use:
// tailwind.config.js
module.exports = {
content: ['./src/**/*.{html,js,jsx,tsx}'],
// Only classes found in these files will be generated
};
3. CSS-in-JS
Libraries like styled-components and Emotion only include CSS for rendered components:
const Button = styled.button`
background: #e94560;
color: white;
/* Only included in CSS if <Button> is rendered */
`;
4. Regular Audits
Schedule quarterly CSS audits. Track total CSS size as a team metric.
Quick Win: Split CSS by Route
Instead of one global stylesheet, split CSS by page:
<!-- Homepage only loads homepage CSS -->
<link rel="stylesheet" href="/css/home.css">
<!-- Blog only loads blog CSS -->
<link rel="stylesheet" href="/css/blog.css">
This is automatic in frameworks like Next.js with CSS Modules.
Results to Expect
| Metric | Before | After |
|---|---|---|
| CSS size | 200KB | 30-50KB |
| FCP | 2.5s | 1.5s |
| Render-blocking time | 400ms | 100ms |
| Lighthouse | +5-15 points | — |
Monitor CSS Bloat Over Time
CSS tends to grow as features are added but rarely shrinks. BadPageSpeed tracks your page performance including resource sizes.
Ready to stop wasting ad spend?
Track your landing page performance, monitor Core Web Vitals, and calculate exactly how much slow pages cost you.
Start Free — No Credit Card