Codectionary / Developer documentation / CSS

Cascade Layers (@layer)

@layer lets you explicitly define the priority order between groups of CSS rules, independent of selector specificity. Styles in a layer declared later always beat styles in an earlier layer, regardless of how specific the earlier layer's selectors are - solving specificity conflicts between resets, frameworks, components, and overrides in a predictable, structured way.

Syntax

@layer name { }
@layer layer1, layer2, layer3;

Examples

Declaring Layer Order

Establishing which layers should win, before any of them are even defined.

@layer reset, base, components, utilities;
@layer base { #card { color: #b45309; } }
@layer utilities { .text-blue { color: #1d4ed8; } }
/* Later layers outrank specificity for these normal declarations.
   Important declarations reverse layer priority. */
  1. The article matches both example selectors.
  2. Among normal declarations in these layers, the later layer outranks specificity from the earlier layer.
  3. Important declarations reverse layer priority, and unlayered normal rules have their own precedence; this example intentionally compares only normal layered rules.
HTML used by this example
<article id="card" class="featured active text-blue"><h3>Layered notice</h3><p>The winning colour comes from the normal rule in the later layer.</p></article>

Layers Beating Specificity

A low-specificity rule in a later layer wins over a high-specificity rule in an earlier layer.

@layer base {
  #card.featured.active { color: red; } /* very high specificity */
}

@layer utilities {
  .text-blue { color: blue; } /* much lower specificity, but wins - later layer */
}
/* These are normal declarations. Important declarations reverse layer priority. */
  1. The article matches both example selectors.
  2. Among normal declarations in these layers, the later layer outranks specificity from the earlier layer.
  3. Important declarations reverse layer priority, and unlayered normal rules have their own precedence; this example intentionally compares only normal layered rules.
HTML used by this example
<article id="card" class="featured active text-blue"><h3>Layered notice</h3><p>The winning colour comes from the normal rule in the later layer.</p></article>

Parameters and values

  • @layer name { } (at-rule): Defines a named cascade layer and its rules
  • @layer a, b, c; (at-rule): Declares layer priority order upfront, without defining rules yet

Best practices

  • Declare your full layer order upfront with @layer name1, name2, name3; even before writing rules, so the priority is clear from the start of the stylesheet
  • Use layers to cleanly separate resets, base styles, component styles, and utility overrides - a common structure that eliminates most specificity conflicts
  • Remember unlayered styles (written outside any @layer) always beat layered styles, regardless of layer order - keep genuinely critical overrides unlayered intentionally
  • This replaces many of the reasons teams historically reached for !important - a properly layered stylesheet rarely needs it

Browser compatibility

chrome
Yes
firefox
Yes
safari
Yes
edge
Yes

These are the existing reference’s support labels, not tested minimum versions. Individual values and APIs can have different support. Check the linked specification before choosing a browser target.

CSS specifications (modules)

Specifications & further reading