CSS: cascade @layer

By Xah Lee. Date: . Last updated: .

What is Cascade Layers

Cascade Layers lets you group CSS rules and specify the priority of each group, using the @layer keyword.

Each group, is called a “layer”.

Effectively, it lets you customize CSS cascade, and is a easy way to manage CSS specificity.

Example. simple cascade layers

/* define layer x1 */
@layer x1 {
 p {
  color: red;
 }
 /* more rule here */
}

/* define layer x2 */
@layer x2 {
 p {
  color: blue;
 }
 /* more rule here */
}

/* layer that appear later has higher priority */

/* rules not declared in any layer, are considered as in implicit final layer, and have higher priority than any explicit layers. */

p {
 color: blue;
}

Default cascade layers

by default, there are these layers, listed from low to high priority:

  1. Browser's style sheet
  2. User's style sheet (set by user in browser settings)
  3. Author's style sheet (of the web page)

Syntax

At-layer statement

/* this is called at-layer statement */
@layer x1, x2, x3;

At-layer block

/* this is at-layer block */
@layer x1 {
 p {
  color: red;
 }
}

At-layer statement. Explicit specification of order

At-layer statement explicitly declares the names and their order.

@layer x1, x2, etc;

/* this defines several layers, and also specify their priority order, from low to high. */
@layer x1, x2, x3;

/* define rules for x1 */
@layer x1 {
 p {
  color: red;
 }
}

/* define rules for x2 */
@layer x2 {
 p {
  color: blue;
 }
}

At-layer statement has no effect on already declared layers

🛑 WARNING: the explicit layer order declaration @layer x1, x2, etc; does not re-specify order if a layer is already declared earlier.

For example, if you put @layer x1, x2, etc; to bottom, it has no effect on layers declared above it.

Easy way to remember order is, later layer in source code always have higher priority.

/* define layer x1 */
@layer x1 {
 p {
  color: red;
 }
}

/* define layer x2 */
@layer x2 {
 p {
  color: blue;
 }
}

/* layer x2 has higher priority than x1, because x2 appear later in source code. */

/* this has no effect */
@layer x2, x1;

Implicit final layer (Unlayered rules)

Rules not in any layer is considered an implicit final layer. It has higher priority than any declared layers.

/* rules not declared in any layer, are considered as in implicit final layer, and have higher priority than any explicit layers. */

p {
 color: blue;
}

div {
 color: blue;
}

/* s------------------------------ */

@layer x1 {
 p {
  color: red;
 }
}

Repeated layers

Repeated layers of the same name are merged. That is, you can append rules to it at a later location.

@layer bb {
 p {
  color: blue;
 }
}

/* append rules to layer bb. */
@layer bb {
 p {
  border: solid 1px grey;
 }
}

Anonymous layers

Layer can be declared without a name.

/* anonymous layer */
@layer {
 color: red;
}

Anonymous layer's priority is at the location of its declaration.

/* example showing layer order */

@layer aa {} /* named */
@layer {} /* anonymous 1 */
@layer bb {} /* named */
@layer {} /* anonymous 2 */

/*
priority order is:
aa ≺ anonymous1 ≺ bb ≺ anonymous2 ≺ (unlayered styles).
 */

Browser support

Cascade Layers is supported in major browsers starting since 2023.

CSS rules priority order

CSS. misc, advanced