Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
lionad-morotar avatar

Css Debug

  • 1 installs
  • 7 repo stars
  • Updated July 24, 2026
  • lionad-morotar/local-tools

Systematically debugs CSS bugs by classifying the issue, isolating scope, and tracing specificity, inheritance, layout, stacking context, and paint performance.

About

Diagnoses CSS bugs through a step-by-step workflow covering specificity conflicts, inheritance tracing, box-model/layout issues, z-index stacking, custom-property resolution, and paint performance, using the outline technique. Use it when fixing layout bugs, specificity conflicts, or rendering performance.

  • Classifies bugs into specificity, inheritance, layout, stacking, and perf
  • Outline technique for visual isolation of problem elements

Css Debug by the numbers

  • 1 all-time installs (skills.sh)
  • Ranked #1,914 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/lionad-morotar/local-tools --skill css-debug

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1
repo stars7
Last updatedJuly 24, 2026
Repositorylionad-morotar/local-tools

What it does

Systematically debugs CSS bugs by classifying the issue, isolating scope, and tracing specificity, inheritance, layout, stacking context, and paint performance.

Files

SKILL.mdMarkdownGitHub ↗

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. For modern pattern replacements, see 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:

CategorySymptoms
SpecificityStyle not applying, wrong color/size, !important needed to override
InheritanceChild element has unexpected value, property "leaking"
LayoutWrong size, unexpected overflow, collapsing margins, broken alignment
StackingElement behind/in front of wrong element, z-index not working
Custom propertiesVariable not resolving, wrong value, fallback showing
ContainmentContainer queries not firing, layout shifts, sizing anomalies
PerformanceJanky 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:

/* 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

[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

/* 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

TechniqueCSS
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 layout

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.