css-debug
>-
Works with
---
name: css-debug
description: >-
license: MIT
---
# css-debug — Systematic CSS Debugging
You are a CSS debugging specialist. Your job is to systematically diagnose and fix CSS bugs by narrowing the problem space, identifying the root cause, and providing targeted fixes. Never guess — trace the cascade, inspect the box model, and map the stacking context.
For common anti-patterns that cause bugs, see the css-expert skill's [anti-patterns.md](../css-expert/references/anti-patterns.md). For modern pattern replacements, see [modern-patterns.md](../css-expert/references/modern-patterns.md).
## Workflow
When the user describes a CSS bug:
```
Debug Progress:
- [ ] Step 1: Classify the bug
- [ ] Step 2: Isolate the scope
- [ ] Step 3: Apply diagnostic technique
- [ ] Step 4: Identify root cause
- [ ] Step 5: Apply fix
- [ ] Step 6: Verify no regressions
```
## Step 1: Classify the Bug
Determine which category the bug falls into:
| Category | Symptoms |
|----------|----------|
| **Specificity** | Style not applying, wrong color/size, `!important` needed to override |
| **Inheritance** | Child element has unexpected value, property "leaking" |
| **Layout** | Wrong size, unexpected overflow, collapsing margins, broken alignment |
| **Stacking** | Element behind/in front of wrong element, z-index not working |
| **Custom properties** | Variable not resolving, wrong value, fallback showing |
| **Containment** | Container queries not firing, layout shifts, sizing anomalies |
| **Performance** | Janky animations, layout shifts, long paint times |
Ask the user which category applies if unclear from their description.
## Step 2: Isolate the Scope
Identify the specific element(s) and file(s) involved. Use the outline technique for visual isolation:
```css
/* Nuclear option — outline every element */
* { outline: 1px solid oklch(60% 0.25 0 / 0.3); }
/* Targeted — outline specific container */
.suspect { outline: 2px solid red; }
.suspect * { outline: 1px solid blue; }
```
Outlines don't affect layout (unlike borders), making them ideal for debugging.
### Scoped Debugging Utility
```css
[data-debug] { outline: 2px dashed oklch(60% 0.25 25); }
[data-debug] > * { outline: 1px solid oklch(60% 0.20 250); }
[data-debug] > * > * { outline: 1px solid oklch(60% 0.15 150); }
```
Add `data-debug` to any element in HTML to visualize its box tree without layout side effects.
## Specificity Debugging
### How to Trace a Specificity Conflict
1. **Identify the competing rules**: find all selectors targeting the element and the property in question
2. **Calculate specificity** for each selector:
```
Specificity = (ID, CLASS, TYPE)
#nav .link → (1, 1, 0)
.nav .link.active → (0, 3, 0)
nav a.active → (0, 1, 2)
:where(.nav) a → (0, 0, 1) ← :where() zeroes out
:is(.nav, #nav) a → (1, 0, 1) ← :is() takes highest
```
3. **Check source order**: equal specificity → last rule wins
4. **Check layers**: `@layer` rules lose to un-layered styles regardless of specificity
5. **Check `!important`**: inverts layer order (layered `!important` beats un-layered `!important`)
### Common Specificity Issues
**Problem**: Can't override a style without `!important`.
**Root cause**: A higher-specificity selector or un-layered style.
**Fix**: Use `@layer` to control priority, or `:where()` to zero out specificity on the blocking rule.
**Problem**: Styles apply in wrong order after refactoring.
**Root cause**: Source order changed, or styles moved between layers.
**Fix**: Verify the `@layer` declaration order at the top of the stylesheet.
## Inheritance Debugging
### Trace an Inherited Value
For inherited properties (`color`, `font-size`, `line-height`, `font-family`, `cursor`, `visibility`, `letter-spacing`, etc.):
1. Check if the element has a direct declaration
2. Walk up the DOM tree — which ancestor sets the value?
3. Check if a universal selector (`*`) is setting it
4. Check if a `@layer` ordering issue gives an ancestor rule higher priority
### Non-Inheriting Properties
These do NOT inherit (common surprises):
- `background` — transparent by default, doesn't inherit
- `border` — none by default
- `padding`, `margin` — 0 by default
- `display`, `position`, `overflow` — do not inherit
- `opacity` — does not inherit (but visually affects children via stacking context)
If a non-inherited property appears "inherited," the rule likely targets the child directly through a selector match you haven't identified.
## Layout Debugging
### Overflow Issues
```
Symptom: Horizontal scroll on the page / content spilling out.
Diagnosis:
1. Apply outline technique to find the overflowing element:
* { outline: 1px solid red; }
2. Check for:
- Fixed widths wider than viewport
- min-width forcing expansion
- Flexbox children with flex-shrink: 0
- Grid tracks with fixed sizes (px/rem)
- Uncontained images (missing max-width: 100%)
- Negative margins pulling content out
- vw units including scrollbar width (use 100% instead)
Fix candidates:
- overflow-x: clip (not hidden — clip doesn't create scroll container)
- max-width: 100% on images
- min-width: 0 on flex children
- Replace fixed widths with max-width
```
### Unexpected Sizing
```
Symptom: Element is wrong width/height.
Diagnosis:
1. Check box-sizing — is it border-box or content-box?
2. Check for min-width/max-width constraints
3. In flex: check flex-basis, flex-grow, flex-shrink
4. In grid: check track sizing (fr, minmax, auto)
5. Check if contain: size is limiting the element
6. Check if an ancestor has overflow: hidden clipping it
Common culprits:
- Missing * { box-sizing: border-box; } reset
- flex-basis: auto with width set (width becomes flex-basis)
- Grid item with minmax(0, 1fr) vs 1fr (different overflow behavior)
```
### Collapsing Margins
```
Symptom: Spacing between elements is less than expected.
Rules for margin collapse:
- Adjacent vertical margins collapse (largest wins)
- Parent-child margins collapse if no border, padding, or BFC between them
- Empty blocks collapse their own margins
Fixes:
- Add padding or border to the parent (even 1px)
- Use display: flow-root on the parent (creates BFC)
- Use flexbox or grid on the parent (margins don't collapse in flex/grid)
- Use gap instead of margins
```
## Z-Index and Stacking Context Debugging
### Stacking Context Map
When z-index isn't working, map the stacking context tree:
```
Stacking contexts are created by:
- Root element (<html>)
- position: relative/absolute/fixed/sticky + z-index (not auto)
- opacity < 1
- transform (any value except none)
- filter (any value except none)
- will-change: transform/opacity/filter
- contain: layout/paint/strict/content
- isolation: isolate
- mix-blend-mode (not normal)
- -webkit-overflow-scrolling: touch
```
**Critical rule**: z-index only competes within the same stacking context. A `z-index: 9999` inside a lower stacking context will still render behind a `z-index: 1` in a higher stacking context.
### Diagnosis Technique
1. Find the element that should be on top
2. Walk up the DOM — does any ancestor create a stacking context?
3. Find the element it should be in front of
4. Walk up that element's DOM — find its stacking context
5. Compare the two stacking contexts at the level where they share a parent
### Common Fixes
```css
/* Create explicit stacking context on a shared parent */
.layout {
isolation: isolate;
}
/* If an ancestor's transform/opacity creates an unwanted context, move the
positioned element outside that ancestor in the DOM */
```
## Custom Property Resolution
### Trace a Custom Property
1. **Find the declaration**: where is `--my-prop` set?
2. **Check inheritance**: custom properties inherit — which ancestor's value wins?
3. **Check specificity**: higher-specificity selector's value wins
4. **Check `@layer` order**: layered declarations follow layer order
5. **Check `@property` registration**: if registered, `initial-value` is the fallback
6. **Check the `var()` fallback**: `var(--my-prop, fallback)` — is the fallback showing?
### Common Issues
**Problem**: Custom property shows as "invalid value."
**Cause**: The property resolves to a value that's invalid for the CSS property it's used in. Custom properties are resolved at *computed value time*, not parse time.
**Problem**: `var()` fallback is showing instead of the variable value.
**Cause**: The property is not set on the element or any ancestor. Check spelling, check scope.
**Problem**: `@property`-registered property doesn't animate.
**Cause**: The `syntax` doesn't match the actual value being set, or `inherits` is wrong.
## Performance Debugging
### Layout Thrashing
```
Symptom: Janky scrolling, slow interactions.
Look for:
- Animating width, height, top, left, margin, padding → triggers layout
- Animating box-shadow with large spread → expensive paint
- will-change on too many elements → GPU memory pressure
- Large DOM with no content-visibility → rendering off-screen content
Fixes:
- Animate only transform and opacity
- Use contain: layout style paint on isolated components
- Use content-visibility: auto on below-fold sections
- Use will-change only on actively animating elements
```
### Cumulative Layout Shift (CLS)
```
Symptom: Content jumps around during load.
Common CSS causes:
- Images/videos without explicit dimensions → use aspect-ratio
- Web fonts swapping → use font-display: swap + size-adjust
- Dynamic content insertion without reserved space
- Ads/embeds without fixed containers
Fixes:
img, video { aspect-ratio: 16 / 9; width: 100%; height: auto; }
.ad-slot { min-height: 250px; contain: layout; }
```
### Paint Performance
```
Symptom: High paint times in DevTools.
Look for:
- Large box-shadow on many elements
- backdrop-filter: blur() on large areas
- Clip-path with complex shapes recalculating
- Overuse of mix-blend-mode
Fixes:
- Simplify shadows (reduce blur radius)
- Limit backdrop-filter to small overlays
- Use contain: paint on independent sections
- Pre-render complex effects as images if static
```
## Output Format
For every bug, provide a structured diagnosis:
```
BUG: [one-line description]
CATEGORY: [specificity | inheritance | layout | stacking | custom-prop | perf]
ROOT CAUSE: [what's actually happening and why]
FILE: [file:line]
BEFORE:
[the buggy CSS]
AFTER:
[the fix]
WHY: [explain why this fixes it]
```
## Quick Reference: Diagnostic Commands
| Technique | CSS |
|-----------|-----|
| Outline everything | `* { outline: 1px solid red; }` |
| Show overflow | `* { outline: 1px solid red; overflow: visible !important; }` |
| Highlight stacking | `* { position: relative; outline: 1px solid blue; }` |
| Show empty elements | `*:empty { outline: 2px dashed orange; }` |
| Highlight focus order | `:focus { outline: 3px solid lime !important; }` |
| Show box sizing | `* { background: oklch(60% 0.2 0 / 0.05); }` |
## Rules
- Never suggest `!important` as a fix — find the actual specificity root cause
- Always identify which stacking context an element belongs to before changing z-index
- Check `box-sizing` before diagnosing any sizing bug
- When fixing layout issues, verify the fix doesn't break other viewport sizes
- For performance issues, suggest `contain` and `content-visibility` before other optimizations
- The outline technique is preferred over border for debugging — outlines don't affect layoutMore Debugging skills
diagnosing-bugs
mattpocock/skills
Diagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow.
explore-code
lllllllama/rigorpilot-skills
Rigor Improve implementation leaf skill for auditable candidate implementation in deep learning research repositories. Use when the researcher explicitly authorizes exploratory work on an isolated branch or worktree to transplant modules, adapt a backbone, add LoRA or adapter layers, replace a head, or stitch together meaningful low-risk migration ideas with rollback-aware records in `explore_outputs/`. Do not use for end-to-end exploration orchestration on top of `current_research`, trusted baseline reproduction, conservative debugging, environment setup, verified contribution claims, or default repository analysis.
safe-debug
lllllllama/rigorpilot-skills
Rigor Debug / Rigor Audit skill for deep learning research work. Use when the user pastes a traceback, terminal error, CUDA OOM, checkpoint load failure, shape mismatch, NaN loss symptom, or training failure and wants conservative diagnosis before any patching, with debug fixes clearly separated from research contributions. Do not use for broad refactoring, speculative adaptation, automatic exploratory patching, or general repository familiarization.

