CSS Debugging Workflow
Debugging CSS is a skill. This guide covers systematic approaches, DevTools mastery, and the specific patterns that resolve the most common CSS bugs — including WordPress-specific issues.
1. The Golden Rule: Work in DevTools First
Never edit your CSS file blindly. Always prototype fixes in browser DevTools first, then paste working code into your source.
- Chrome: Press
F12→ Elements tab → Styles panel. - Firefox: Has the best Grid and Flexbox inspector — use it for layout bugs.
- Safari: Requires DevTools to be enabled in Preferences first.
2. The Outline Debug Technique
Apply colored outlines to every element to visualize the box model without affecting layout:
/* Paste this temporarily to see all boxes */
* { outline: 1px solid red; }
/* Color-coded by element type */
div { outline: 1px dashed red; }
p { outline: 1px dashed blue; }
span { outline: 1px dashed green; }
img { outline: 2px solid orange; }
/* Or use the CSS Debug bookmarklet concept */
* { background-color: rgba(255,0,0,0.05) !important; }
3. Reading the DevTools Styles Panel
Styles Panel Anatomy:
┌─────────────────────────────────────────────────────┐
│ element.style { ← Inline styles │
│ color: red; │
│ } │
│ │
│ .card { ← ──────────────── Your CSS file │
│ background: #1a1a1a; │
│ } │
│ │
│ ~~.card { color: blue; }~~ ← STRUCK THROUGH │
│ ← This rule was overridden by a more specific rule │
│ │
│ user agent stylesheet { ← Browser default │
│ display: block; │
│ } │
└─────────────────────────────────────────────────────┘
Struck-through rules are your primary debugging signal — they show exactly what was overridden and by what.
4. The Specificity Debugging Flowchart
My CSS rule doesn't apply. Why?
│
├── Is it struck through in DevTools?
│ YES → Specificity conflict
│ ├── Is winning rule from theme/plugin? → Increase specificity or use @layer
│ ├── Is winning rule using !important? → Match with !important (last resort)
│ └── Is winning rule inline style=""? → Inspect source, add your class
│
├── Not struck through, but not showing?
│ → CSS not loading
│ ├── Check: is the file enqueued?
│ ├── Check: browser cache (Ctrl+Shift+R)
│ └── Check: syntax error earlier in file (breaks rest of file)
│
└── Is the property inherited but overridden?
→ Use Computed tab → search the property → see where it comes from
5. The Computed Tab
The Computed tab shows the final resolved value of every property — accounting for all cascade, specificity, and inheritance:
- Search for a property name (e.g.,
font-size) to see exactly what value applies. - Click the triangle
▶next to any property to see which rule set that value and from which file. - Use this when struck-through analysis isn't enough.
6. Layout Debugging: Flex and Grid Inspectors
In Chrome:
- Elements panel → Click the
flexorgridbadge next to an element → Visual overlay appears.
In Firefox (Superior):
- Layout tab → Grid / Flex sections → Toggle line numbers, track sizes, area names.
/* Add temporary visual grid lines with this technique */
.debug-grid {
background-image:
linear-gradient(rgba(255,0,0,0.1) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,0,0,0.1) 1px, transparent 1px);
background-size: 8px 8px;
}
7. Common Bug Index
Bug: Element Has Unexpected Height/Width
/* Diagnosis */
* { outline: 1px solid red; } /* Reveal box extents */
/* Common causes */
.fix-1 { box-sizing: border-box; } /* Padding adding to width */
.fix-2 { height: auto; } /* Height set when it shouldn't be */
.fix-3 { min-height: 0; min-width: 0; } /* Flex/Grid children not shrinking */
Bug: Sticky Not Working
/* Checklist */
.sticky { position: sticky; top: 0; } /* ← must have threshold */
/* Check parent for these — any of these BREAK sticky: */
.parent { overflow: hidden; } /* ← BREAKS sticky — remove */
.parent { overflow: auto; } /* ← BREAKS sticky — remove */
.parent { overflow: clip; } /* ← OK — use this instead */
/* Must have enough content to scroll */
/* Parent height must be taller than sticky element */
Bug: Z-index Not Working
/* z-index only works on positioned elements */
.above { position: relative; z-index: 10; } /* NOT: position: static */
/* Check for stacking context breakers — these create isolated z-index contexts: */
/* opacity < 1, transform, filter, will-change, isolation: isolate */
.parent { transform: translateZ(0); } /* Parent creates context — child z-index is scoped */
/* Debug stacking */
.element { isolation: isolate; } /* Create intentional stacking context */
Bug: Flexbox Item Overflows
.flex-child { min-width: 0; } /* Fix: flex children default to min-width: auto */
.flex-child { overflow: hidden; } /* Overflow hidden also resets flex min-width */
Bug: CSS Grid Item Not Sizing Correctly
/* Item doesn't expand */
.grid-item { min-width: 0; min-height: 0; } /* Same as flex */
/* Image not fitting grid cell */
.grid-item img { width: 100%; height: 100%; object-fit: cover; }
Bug: Margin Collapsing
/* Space between elements IS NOT the sum of margins */
/* Fix: use gap in flex/grid instead of margins */
.flex-col { display: flex; flex-direction: column; gap: 1.5rem; }
/* Or create BFC on parent */
.parent { display: flow-root; }
8. WordPress-Specific Debugging
Step 1: Identify the Conflicting Rule
1. Open DevTools → Elements
2. Click the styled element
3. Find your property in Styles panel — struck through?
4. Read the selector of the winning rule
Step 2: Beat the Conflicting Rule
/* Winning rule was: .site-header .nav a — specificity 0,2,1 */
/* Match: */
.site-header .main-nav a { color: var(--accent); }
/* Or outspecify: */
body .site-header .nav a { color: var(--accent); }
/* Safest pattern: chain-qualify the existing selector */
.site-header.site-header .nav a { color: var(--accent); } /* doubled class */
Step 3: Cache
Always do hard-refresh before debugging:
- Chrome/Firefox: Ctrl + Shift + R (Mac: Cmd + Shift + R)
- Clear plugin cache: LiteSpeed → Purge All
- Disable cache completely during dev: DevTools → Network → Disable cache ✓
9. CSS Validation
Check for syntax errors: Jigsaw CSS Validator
Common syntax errors that silently break everything after them:
/* Missing semicolon — breaks all rules after this one */
.card { background: red } /* ← missing ; */
.card { color: white; } /* ← this rule now doesn't work */
/* Unclosed bracket */
.card {
background: red;
/* ← missing closing } — breaks entire rest of file */
.next-rule { color: blue; } /* never applied */
10. AI-Assisted Debugging
Use Claude or ChatGPT to debug quickly:
My CSS rule doesn't work. Here is the element HTML:
[paste element HTML from DevTools → right-click → Copy outerHTML]
Here is the winning CSS rule (from DevTools struck-through):
[paste conflicting rule]
Here is my CSS:
[paste your rule]
How do I make my rule win without using !important?