Dead CSS Removal Workflow
Created: 2025-11-28
Tools: Lighthouse MCP, CSS MCP, Browser Tools, grep
Overview
Removing unused CSS improves page load performance, reduces bundle size, and makes stylesheets easier to maintain. However, there is no magic button that safely removes CSS automatically—static analysis tools can't detect dynamically-generated class names (Stimulus, Rails helpers, JavaScript).
This document outlines a safe, methodical workflow using AI-assisted tools available in Cursor.
Why Not Just Use PurgeCSS?
Tools like PurgeCSS work well for static sites but are risky for Rails applications because:
- Dynamic classes:
class: "btn-#{variant}"in Ruby - Stimulus controllers: Classes added via JavaScript
- Conditional rendering: Classes only used in specific states
- Third-party components: Bootstrap, Font Awesome classes
The workflow below uses targeted analysis instead of aggressive purging.
Phase 1: Identify Unused CSS
Step 1.1: Run Lighthouse Audit
First, identify which CSS files have the most unused code:
Run a Lighthouse performance audit on https://www.warmlyyours.me:3000
Focus on the "Reduce unused CSS" opportunity
Expected output: File paths, estimated savings, and coverage percentages.
Step 1.2: Get Detailed Coverage Report
For deeper analysis, use Chrome DevTools Coverage:
Navigate to https://www.warmlyyours.me:3000
Take a screenshot showing the page loaded
Then manually:
- Open DevTools → Coverage tab (Cmd+Shift+P → "Coverage")
- Click reload to capture CSS usage
- Look for files with high "Unused Bytes" percentage
Step 1.3: Analyze Specific Stylesheets
Once you identify problem files, analyze their complexity:
Analyze the CSS in client/stylesheets/www/03-components/page-blog.scss
for unused patterns and complexity issues
Phase 2: Verify Before Deleting
Step 2.1: Search for Class Usage
Never delete a class without searching the entire codebase first.
Search for the class "hero-wrapper-old" in app/views, app/components,
and client/js directories. Is it used anywhere?
Or use grep directly:
# Search for a specific class
grep -r "hero-wrapper-old" app/ client/ --include="*.erb" --include="*.rb" --include="*.js" --include="*.scss"
# Search for partial class names (dynamic classes)
grep -r "hero-wrapper" app/ client/ --include="*.erb" --include="*.rb"
Step 2.2: Check for Dynamic Class Generation
Look for patterns that generate classes dynamically:
# Rails helpers
class: "card-#{type}"
class_names("active" => condition)
# Stimulus
element.classList.add("loading")
this.element.classList.toggle("open")
Ask the AI:
Are there any dynamic class patterns in app/helpers or app/javascript
that might generate classes starting with "hero-"?
Step 2.3: Check Bootstrap/Framework Classes
Before removing a class, verify it's not from Bootstrap:
Is "d-flex" a Bootstrap utility class? What does it do?
Check browser compatibility for the CSS property "gap" in flexbox
Phase 3: Safe Removal
Step 3.1: Remove One Class at a Time
Don't batch-delete. Remove classes individually and verify:
Delete the .hero-wrapper-old class from client/stylesheets/www/03-components/hero.scss
Step 3.2: Rebuild Assets
After each change:
eval "$(mise activate zsh)" && yarn build
Step 3.3: Visual Regression Check
Take before/after screenshots to catch layout shifts:
Take a screenshot of https://www.warmlyyours.me:3000
Compare with the previous state. Look for:
- Missing elements
- Broken layouts
- Shifted content
- Missing hover states
Step 3.4: Test Critical Pages
After removing CSS, audit affected pages:
Run Lighthouse on the homepage, a product page, and the contact form
to verify no accessibility or performance regression
Phase 4: Ongoing Maintenance
4.1: Prevent Dead CSS Accumulation
- Use component-scoped CSS: Keep styles close to their components
- Document class purpose: Add comments for non-obvious classes
- Review during PRs: Check if new CSS duplicates existing styles
- Regular audits: Run Lighthouse monthly
4.2: Safe Patterns for Dynamic Classes
When you need dynamic classes, use allowlists:
// _safelist.scss - Classes that might appear unused but are dynamically generated
// Do not remove these without checking JavaScript/Ruby code
// Used by Stimulus controllers
.is-loading { }
.is-active { }
.is-open { }
// Used by Rails helpers
.alert-success { }
.alert-danger { }
.alert-warning { }
4.3: Document Removed CSS
Keep a log of what was removed and why:
## CSS Cleanup Log
### 2025-11-28
- Removed `.hero-wrapper-old` - replaced by `.hero-container` in refactor
- Removed `.legacy-button` - unused since Bootstrap 5 migration
- Kept `.card-highlight` - used dynamically in product_card_helper.rb
Quick Reference: MCP Commands
| Task | Prompt |
|---|---|
| Audit performance | Run Lighthouse audit on [URL] |
| Check CSS property | What are the values for CSS [property]? |
| Browser support | Is CSS [feature] supported in Safari? |
| Analyze CSS file | Analyze the CSS in [file] for issues |
| Search codebase | Search for class "[name]" in app/views |
| Take screenshot | Take a screenshot of [URL] |
Example Workflow Session
Here's a complete example of removing dead CSS:
1. Identify Problem
Run Lighthouse performance audit on https://www.warmlyyours.me:3000/floor-heating
What's the "Reduce unused CSS" recommendation?
AI Response: "The page has 45KB of unused CSS, primarily from webpack-bundle.css. Top unused selectors include .legacy-carousel, .old-modal, .deprecated-grid..."
2. Verify Usage
Search for "legacy-carousel" in app/views, app/components, and client/js.
Is this class used anywhere?
AI Response: "No matches found in app/views or app/components. Found 1 match in client/stylesheets/www/03-components/carousel.scss (the definition itself)."
3. Check for Dynamic Usage
Search for "legacy" or "carousel" patterns in app/helpers that might
generate this class dynamically
AI Response: "No dynamic patterns found that would generate legacy-carousel."
4. Remove Safely
Delete the .legacy-carousel class and its related styles from
client/stylesheets/www/03-components/carousel.scss
5. Rebuild and Verify
eval "$(mise activate zsh)" && yarn build
Take a screenshot of https://www.warmlyyours.me:3000/floor-heating
6. Final Audit
Run Lighthouse on the same page. Did the unused CSS decrease?
Troubleshooting
"I deleted a class and something broke"
git checkout -- [file]to restore the file- Search more broadly:
grep -r "partial-class-name" . - Check JavaScript files for
classList.add()calls - Look for Ruby string interpolation:
"class-#{variable}"
"Lighthouse shows unused CSS but I can't find it"
- The CSS might be from a vendor library (Bootstrap, Font Awesome)
- The CSS might only be used on other pages
- The CSS might be loaded but apply to elements not on the current page
"The class is used but Lighthouse still flags it"
This is normal—Lighthouse only analyzes the current page state. A class used on hover, after JavaScript runs, or on different screen sizes may be flagged as "unused" but is actually needed.