← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

CSS Cascade Layers (@layer)

frontend Intermediate

TL;DR

CSS @layer lets you explicitly define the order in which style groups are applied in the cascade — styles in a later layer always win over earlier ones regardless of specificity, eliminating specificity wars in large codebases.

Explanation

The CSS cascade determines which rule wins when multiple rules target the same element. Before cascade layers, specificity (ID > class > element) and source order determined the winner — leading to escalating specificity arms races in large teams. @layer (introduced in 2022, supported in all modern browsers) adds a new cascade dimension above specificity: a rule in a later-declared layer wins over all rules in earlier layers, regardless of how specific those earlier rules are. Typical usage: @layer reset, base, components, utilities — utilities always win over components which always win over base, without any need for !important or high-specificity selectors. Third-party CSS can be wrapped in a named layer to ensure your own styles always override it. Unlayered styles (those outside any @layer) have the highest priority — a useful escape hatch. Layers interact with @import and can be nested.

Watch Out

Styles outside any @layer have the highest cascade priority — if you partially adopt layers, unlayered third-party CSS will override your layered component styles, which is the opposite of what you usually want.

Common Misconception

A higher-specificity selector in an earlier layer does NOT win over a lower-specificity rule in a later layer — layer order trumps specificity entirely.

Why It Matters

Cascade layers eliminate specificity wars in large codebases and design systems — you can integrate third-party CSS without fearing it will override your components, and utilities are guaranteed to win without !important.

Common Mistakes

  • Declaring layers in the wrong order — the last declared layer has highest priority; @layer reset, utilities gives utilities the win, not reset.
  • Mixing layered and unlayered styles unintentionally — styles outside any @layer have higher priority than all layered styles.
  • Wrapping everything in a layer including utility overrides — unlayered utilities have highest priority by default, which is usually what you want.

Avoid When

  • Avoid cascade layers in small single-file stylesheets where specificity is not yet a problem — the added mental model is not worth it.
  • Do not use layers in projects that must support older browsers (pre-2022) without a PostCSS polyfill.

When To Use

  • Use @layer in any codebase with third-party CSS (Tailwind base, Bootstrap reset) — wrap third-party styles in a named layer so your styles always win.
  • Use layers in design systems to enforce a predictable override hierarchy: reset → base → components → utilities.
  • Use them when migrating a legacy codebase with high-specificity selectors — wrap legacy CSS in an early layer so new code can override without specificity gymnastics.

Code Examples

💡 Note
The bad example adds increasingly specific selectors to override third-party styles — a brittle arms race. The fix wraps third-party CSS in an early layer; your utility layer always wins regardless of selector specificity.
✗ Vulnerable
/* Specificity war — escalating selectors to override third-party CSS */
.card { background: white; }           /* third-party: specificity 0,1,0 */
div.card.override { background: blue; } /* your fix: 0,2,1 — fragile */
#app div.card { background: blue; }     /* next escalation: 1,1,1 */
✓ Fixed
/* Cascade layers — layer order determines winner, not specificity */
@layer reset, base, components, utilities;

@layer reset {
    * { box-sizing: border-box; margin: 0; }
}

@layer components {
    .card { background: white; } /* third-party goes here */
}

@layer utilities {
    .bg-blue { background: blue; } /* always wins — later layer */
}

Added 31 Mar 2026
Views 46
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
3 pings W 0 pings T 0 pings F 0 pings S 0 pings S 4 pings M 0 pings T 25 pings W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
ChatGPT 26 Amazonbot 21 Perplexity 6 Google 2 Ahrefs 1
crawler 55 crawler_json 1

✓ schema.org compliant