2 min read

CSS Layers (@layer)

CSS Cascade Layers (@layer) provide a way to manage the specificity and order of style rules explicitly. They allow you to group styles into layers and define the precedence of those layers, solving many issues related to specificity wars and !important.

1. The Problem: Specificity Wars

Traditionally, CSS relies heavily on specificity. If a 3rd-party library uses a high-specificity selector (e.g., #id .class), overriding it requires an even higher specificity or !important. This leads to messy, hard-to-maintain code.

2. The Solution: Layers

With @layer, the order of the layers determines precedence, not the specificity of the selectors within them.

  • Styles in a higher-priority layer always override styles in a lower-priority layer, regardless of selector specificity.
  • Specificity still matters within a single layer.

3. Defining Layers

You can define layers using the @layer at-rule.

@layer base, components, utilities;

@layer base {
  h1 { color: blue; }
}

@layer components {
  h1 { color: green; } /* Wins because 'components' is after 'base' */
}

4. Layer Ordering

The order in which layers are first defined determines their priority.

/* Define order explicitly */
@layer reset, framework, custom;

/* 'custom' wins over 'framework', which wins over 'reset' */

If you don't define the order upfront, they are ordered by appearance.

5. Unlayered Styles

Styles that are not inside any layer always have higher priority than styles inside layers.

@layer my-layer {
  p { color: red !important; }
}

p { color: blue; } /* This wins! (Unlayered > Layered) */

This design ensures that your main page styles (if unlayered) can easily override libraries loaded into layers.

6. Importing into Layers

You can load external stylesheets directly into a layer.

@import url('bootstrap.css') layer(framework);

programming/css/css programming/css/specificity programming/css/css3