Starter Core concepts Cascade Layers

Core concept 01

Cascade Layers

Declare priority order once. Layer order beats specificity between layers — forever eliminating !important wars and load-order fragility.

The problem

CSS specificity is a good rule within a single codebase. But when utilities, components, resets, and third-party styles all compete, the system breaks down. The only escape was increasing specificity or reaching for !important — both of which make the problem worse.

✗ Without layers
/* Specificity: 0,1,0 */ .card { background: white; } /* Need to override? More specificity. */ .page .card { background: ivory; } /* That broke something... */ #app .page .card { background: ivory; } /* Fine. */ .card { background: ivory !important; }
✓ With layers
@layer components, utilities; @layer components { .card { background: white; } } @layer utilities { /* Always wins — no !important */ .bg-ivory { background: ivory; } }

How layers work

The @layer at-rule creates named buckets in the cascade. Within a layer, specificity works exactly as normal. But between layers, the layer order declared at the top of your stylesheet is the authority — not specificity.

The key insight

A class selector in @layer utilities will always beat an ID selector in @layer components — because utilities was declared after components. Layer order is the new specificity.

How it works
/* Declare layer order once — first declaration wins */
@layer reset, tokens, base, components, utilities;

/* Later layers always win, regardless of selector specificity */
@layer components {
  #high-specificity.card { color: red; }  /* specificity 1,1,0 */
}

@layer utilities {
  .text-blue { color: blue; }  /* specificity 0,1,0 — but wins */
}

Try it

The card below has a blue background from a high-specificity #id.class rule inside the unlayered stylesheet. Click the button to add .utility-wins — a lower-specificity class that overrides it because of layer order.

Interactive demo

Demo card

Styled by #layer-demo-card.demo-card

Specificity 1,1,0. In normal CSS this would be nearly unbeatable. Try adding the utility class.

component rule — active utility class — not applied
Click "Add .utility-wins" to run the demo.

The five-layer stack

This starter declares five layers in css/main.css. The order is fixed — it never changes. Files can be added or imported in any order; the declaration controls everything.

css/main.css
@layer reset, tokens, base, components, utilities;

@import "./reset.css";
@import "./tokens.css";
@import "./base.css";
@import "./components.css";
@import "./utilities.css";
reset Browser normalisation — box-sizing, margin removal, baseline defaults lowest priority
tokens All CSS custom properties — primitives, semantic tokens, dark mode
base Element-level defaults — h1, p, a, input, table, details
components .card, .btn, .site-nav — semantic, purpose-named UI patterns
utilities .flex, .mt-8, .text-secondary — single-purpose escape valves highest priority

Rules to follow

Never write styles outside a layer

Unlayered styles have higher priority than any @layer rule. A style written at the top level of a stylesheet will beat everything in your layer stack.

Anti-pattern

Writing styles outside a layer block — even accidentally — will override your entire layer architecture. Every rule in this project must live inside a named layer.

✗ Unlayered — beats everything
/* This is NOT in a layer */ .card { background: red; /* beats ALL layers */ }
✓ Layered — respects order
@layer components { .card { background: var(--surface-raised); } }

Never use !important

If you feel the need for !important, you're in the wrong layer. Move the rule to a higher-priority layer and it will win without it.

Layer reference

Layer File Purpose Add new rules here?
reset reset.css Browser normalisation Rarely
tokens tokens.css All CSS custom properties For new tokens
base base.css Element-level defaults For new element styles
components components.css Named UI patterns Yes — for new components
utilities utilities.css Single-purpose helpers Yes — for new utilities