Basic @layer setup
Declare cascade layers once to control which styles win — by order, not specificity.
Later layers always win — regardless of selector specificity.
Quick implementation
/* Declare layer order first — this single line controls priority */
@layer reset, base, components;
@layer reset {
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; }
}
@layer base {
body { font-family: system-ui, sans-serif; line-height: 1.5; }
h1 { font-size: 2rem; }
}
@layer components {
/* Wins over reset and base — even with low-specificity selectors */
h1 { font-size: clamp(1.5rem, 4vw, 3rem); }
.card { border-radius: 0.5rem; padding: 1rem; }
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer setting up a scalable CSS architecture.
Goal: Set up CSS cascade layers using @layer — no JavaScript.
Technical constraints:
- Declare all layer names in a single @layer reset, base, components; statement at the top of the stylesheet.
- Each layer is defined separately with @layer name { ... } blocks.
- Later layers always win over earlier layers, regardless of selector specificity.
- Use oklch() for any demo colors, not hex or rgba().
- Do not use !important — layers make it unnecessary for typical overrides.
Framework variant (pick one):
A) Vanilla CSS — a standalone stylesheet with three layers: reset, base, components.
B) PostCSS — show how to split layers across multiple files using @import within each @layer.
Edge cases to handle:
- Unlayered styles (styles outside any @layer) always beat layered styles — treat unlayered as the highest implicit layer or wrap everything in layers.
- Third-party stylesheets loaded before your layers are implicitly unlayered — wrap them: @layer third-party { @import url(...); }.
- Inline styles and !important still override layers as per normal cascade rules.
Return CSS only.
Why this matters in 2026
Cascade layers solve the specificity arms race that has plagued large CSS codebases for years. Before @layer, a low-specificity reset rule could be accidentally overridden by a slightly more specific base style — or you'd reach for !important and make things worse. Layers make the priority order explicit and unambiguous: components beats base beats reset, full stop.
The logic
The single declaration @layer reset, base, components; establishes the cascade order. Layers listed later have higher priority. When styles are defined inside @layer reset { ... }, they are explicitly placed in the reset layer — even if that block appears after a @layer components { ... } block in the file. The layer order declaration, not the source order of the blocks, determines which wins.
This separation of order-declaration from style-definition is the key insight. You can split layer blocks across multiple files and import them in any order — the initial @layer declaration is all that matters for priority.
Accessibility & performance
Cascade layers have no runtime cost — they are a purely static CSS feature resolved at parse time. Browser support is excellent (all major browsers since 2022). The main gotcha is unlayered styles: any CSS not inside a @layer block is treated as if it belongs to a higher priority implicit layer, so it will beat all your declared layers. Wrap third-party stylesheets in a named layer to prevent this: @layer vendor { @import url("library.css"); }.