CSS @layer At-Rule
The @layer at-rule organizes CSS rules into cascade layers and controls which styles take precedence when declarations conflict. It allows developers to manage styles from different sources, such as resets, frameworks, components, and utilities, without relying entirely on selector specificity.
@layer Syntax
The @layer at-rule has two main forms: a statement that declares layer names and a block that contains CSS rules.
Statement Syntax
@layer reset, components, utilities;
This statement declares three named cascade layers and establishes their order without adding any styles.
Block Syntax
@layer components {
.button {
background-color: #0056b3;
color: #fff;
}
}
This block creates or adds styles to the named components layer.
A named layer can be declared more than once. Additional blocks with the same name contribute rules to the existing layer.
How @layer Works
CSS normally resolves conflicting declarations using factors such as origin, importance, specificity, and source order. Cascade layers add another level of control by grouping declarations into explicitly ordered layers.
@layer base, theme;
@layer base {
.heading {
color: #333;
}
}
@layer theme {
.heading {
color: #0056b3;
}
}
The heading appears blue because the theme layer has higher priority than the base layer for normal declarations.
Layer priority is considered before selector specificity when comparing declarations of the same origin and importance.
Once layer priority has been resolved, the normal cascade rules determine which declaration wins within the selected layer.
Layer Order and Priority
The order in which cascade layers are first declared determines their priority.
@layer reset, framework, components, utilities;
For normal declarations, layers declared later have higher priority.
| Layer | Normal Declaration Priority |
|---|---|
reset |
Lowest |
framework |
Higher than reset |
components |
Higher than framework |
utilities |
Highest among these layers |
Declaring the order near the beginning of a stylesheet makes it easier to manage priorities as additional CSS rules are added.
Once a layer has been created, declaring its name again does not change its position in the layer order.
@layer base, theme;
@layer theme {
p {
color: blue;
}
}
@layer base {
p {
color: red;
}
}
The paragraph appears blue even though the base block appears later in the stylesheet. The original layer declaration established the priority.
Layers and Specificity
Cascade layers make it possible for a less specific selector in a higher-priority layer to override a more specific selector in a lower-priority layer.
@layer framework, custom;
@layer framework {
#content .button {
background-color: #777;
}
}
@layer custom {
.button {
background-color: #0056b3;
}
}
The button has a blue background because the custom layer has higher priority, even though the selector in the framework layer has greater specificity.
Specificity still matters when competing declarations belong to the same layer.
@layer components {
.button {
color: #333;
}
.toolbar .button {
color: #0056b3;
}
}
For a button inside an element with the toolbar class, the more specific selector sets the text color to blue.
Unlayered Styles
CSS rules written outside any explicit cascade layer are called unlayered styles.
For normal declarations of the same origin, unlayered styles take precedence over declarations in named or anonymous layers.
.message {
color: #dc3545;
}
@layer theme {
.message {
color: #0056b3;
}
}
The message appears red because the unlayered normal declaration has higher priority, even though the layered declaration appears later.
This behavior is useful when introducing cascade layers into an existing stylesheet. However, unlayered styles should be considered when planning the overall layer structure.
Important Declarations
The !important flag reverses the normal priority order of cascade layers.
For important declarations of the same origin, earlier layers have higher priority than later layers. Important declarations inside layers also take precedence over unlayered important declarations.
@layer base, theme;
@layer base {
.notice {
color: #dc3545 !important;
}
}
@layer theme {
.notice {
color: #0056b3 !important;
}
}
The notice appears red because the base layer was declared first and has higher priority for important declarations.
| Declaration Type | Priority Rule |
|---|---|
| Normal layered declarations | Later layers have higher priority. |
| Normal unlayered declarations | Take precedence over normal layered declarations. |
| Important layered declarations | Earlier layers have higher priority. |
| Important unlayered declarations | Have lower priority than important layered declarations of the same origin. |
These rules describe layer priority within the same cascade origin. User styles, browser styles, inline styles, animations, and transitions also participate in the overall CSS cascade.
Use !important sparingly. Cascade layers are intended to reduce the need for importance-based overrides.
Nested Layers
Cascade layers can contain other layers, allowing related styles to be organized into smaller groups.
@layer components {
@layer buttons {
.button {
padding: 10px 20px;
}
}
@layer cards {
.card {
padding: 20px;
}
}
}
The nested layers are named components.buttons and components.cards.
Dot notation can also be used to reference nested layers directly.
@layer components.buttons {
.button {
border-radius: 4px;
}
}
This adds another declaration to the existing components.buttons layer.
Within a parent layer, nested layers have their own priority order. For normal declarations, styles written directly in the parent layer take precedence over conflicting styles in its nested layers.
Anonymous Layers
An anonymous cascade layer is created by omitting the layer name from an @layer block.
@layer {
.alert {
background-color: #fff3cd;
}
}
Anonymous layers participate in the cascade according to the order in which they are created.
Unlike named layers, anonymous layers cannot be referenced later to add more declarations.
@layer {
.box {
color: red;
}
}
@layer {
.box {
color: blue;
}
}
These are two separate anonymous layers. The box appears blue because the second anonymous layer has higher priority for normal declarations.
Importing Styles into Layers
The @import at-rule can place an external stylesheet into a named or anonymous cascade layer.
Importing into a Named Layer
@layer framework, components;
@import "framework.css" layer(framework);
@import "components.css" layer(components);
The imported stylesheets are assigned to their corresponding layers. Normal declarations in components have higher priority than those in framework.
Importing into an Anonymous Layer
@import "third-party.css" layer;
This creates a new anonymous layer containing the imported stylesheet.
Import statements must appear before ordinary style rules and @layer blocks. Layer-order statements may appear before imports.
Placing third-party stylesheets in lower-priority layers makes it easier to override their normal declarations without increasing selector specificity.
@layer Example
The following example defines three layers to control the appearance of a button. The utilities layer has the highest priority among the three for normal declarations.
<button class="demo-button">Layered Button</button>
@layer base, components, utilities;
@layer base {
button {
padding: 12px 20px;
border: 0;
font-size: 16px;
}
}
@layer components {
.demo-button {
background-color: #0056b3;
color: #fff;
border-radius: 4px;
}
}
@layer utilities {
.demo-button {
background-color: #198754;
}
}
The button has white text, rounded corners, and a green background. The green background from the utilities layer overrides the blue background from the components layer.
Try changing the layer declaration to @layer base, utilities, components;. The button background becomes blue because components now has higher priority than utilities.
Browser Support
The @layer at-rule is Baseline Widely available and has been supported across major browsers since March 2022. See Can I Use? for browser compatibility information.
Specifications
The @layer at-rule is defined in CSS Cascading and Inheritance Level 5. The specification describes named and anonymous layers, layer ordering, nested layers, and how declarations in layers participate in the CSS cascade.
