CSS Cascade Layers Table

PieceWhat it doesField note
@layer base { ... }Declares a named layerLayers stack in first-declaration order
@layer base, components, utilities;Pre-declares layer orderThe one-line layer map - declared before any styles
@layer components { .btn { ... } }Styles in a named layerLower layers lose to higher layers regardless of specificity
unlayered stylesHighest priorityCSS outside @layer always beats layered styles
@layer base.ui { ... }Nested layerDots create hierarchy: base.ui is inside base
!important in layersREVERSES layer orderImportant flips the priority: base !important beats utilities !important
Reference: the MDN @layer reference. Cascade layers solve the problem that specificity cannot: resetting a framework without !important wars. The layer order line (@layer base, components, utilities;) is the ONLY thing that matters - later layers always win regardless of specificity, so utilities in the last layer beat everything in earlier layers without needing higher specificity. Bottom line: think of layers as a stack of transparent sheets - you design the sheet order first, then place rules on the right sheet. Related tools: inheritance table, selectors table, and display table.

Cascade layers (@layer) solve the problem specificity cannot: resetting a framework without !important wars. Layer order is declared FIRST, then rules are placed on named layers - later layers always win regardless of specificity, so utilities in the last layer beat everything in earlier layers without needing higher specificity.

Bottom line: think of layers as a stack of transparent sheets - you design the sheet order first (the one-line layer map), then place rules on the right sheet. Unlayered styles always beat layered styles (they sit above the stack), which means your utility overrides never fight the framework's base styles.

The honest part: the !important reversal is the most surprising behavior and the most useful. Inside layers, !important REVERSES the priority: the FIRST layer's !important beats the LAST layer's !important. This means a base layer can set important defaults that utility layers cannot accidentally override - the framework's reset stays reset even against aggressive utilities.

How to use

  1. Declare the layer map first: @layer base, components, utilities; - the order in this one line controls everything.
  2. Place rules by role: resets and defaults in base, components in the middle, single-purpose overrides in utilities (last).
  3. Use !important deliberately within layers: its reversed priority makes base-layer resets stick against all later non-important styles.

Frequently asked questions

What problem do cascade layers solve that specificity cannot?

Specificity wars. Without layers, overriding a framework's button style requires either higher specificity (more selectors, !important) or restructuring the framework's CSS. With layers, the framework sits in a LOWER layer and your overrides sit in a HIGHER layer - the override wins by layer order alone, regardless of specificity. The conflict disappears because the two rules are on different sheets, not competing on the same one.

Why does !important reverse the layer order?

By design: !important within a layer means 'this rule must not be casually overridden within its scope'. Reversing the priority makes the EARLIEST layer's !important win, which gives the base layer (resets, accessibility defaults) a protected floor that utility layers cannot accidentally steamroll. Without the reversal, a single aggressive utility could break a base accessibility rule. The reversal makes the base layer's !important authoritative.

Do unlayered styles always beat layered styles?

Yes - unlayered author styles sit ABOVE all named layers in the cascade. This is intentional: it means your quick fixes and one-off overrides don't need to be placed in a layer to win. But it also means unlayered styles break the layer architecture - a single unlayered rule can override an entire layer system. The discipline: put everything in a layer, even if the layer is just called 'misc', so the layer order remains the single source of truth.

How do I migrate an existing project to cascade layers?

Start with the layer map: @layer reset, base, layout, components, utilities; declared at the very top. Then move existing styles into layers one group at a time - the reset first (lowest priority), utilities last. Unlayered styles still beat all layered styles during migration, so the transition is gradual: each move into a layer makes that group lose to unlayered overrides, which you then place in the correct higher layer. The process is incremental; nothing breaks mid-migration.

Related tools