@layer
Baseline 2022
Newly available
Since March 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
The @layer
CSS at-rule is used to declare a cascade layer and can also be used to define the order of precedence in case of multiple cascade layers.
Try it
Syntax
/* statement at-rules */
@layer layer-name;
@layer layer-name, layer-name, layer-name;
/* block at-rules */
@layer {rules}
@layer layer-name {rules}
where:
- layer-name
-
Is the name of the cascade layer.
- rules
-
Is the set of CSS rules in the cascade layer.
Description
Rules within a cascade layer cascade together, giving more control over the cascade to web developers. Styles that are not defined in a layer always override styles declared in named and anonymous layers.
The following diagram shows layer priorities where layers are declared in 1, 2, ..., N order.
The declaration order matters. The first declared layer gets the lowest priority and the last declared layer gets the highest priority. However, the priority is reversed when the !important
flag is used.
The @layer
at-rule is used to create a cascade layer in one of three ways.
The first way is to use a @layer
block at-rule to create a named cascade layer with the CSS rules for that layer inside, like so:
@layer utilities {
.padding-sm {
padding: 0.5rem;
}
.padding-lg {
padding: 0.8rem;
}
}
The second way is to use a @layer
statement at-rule to create one or more comma-separated named cascade layers without assigning any styles. This can be a single layer, as shown below:
@layer utilities;
Multiple layers can be defined at once, as shown below:
@layer theme, layout, utilities;
This is useful because the initial order in which layers are declared indicates which layer has precedence. As with declarations, the last layer to be listed will win if declarations are found in multiple layers. Therefore, with the preceding example, if a competing rule was found in theme
and utilities
, the one in utilities
would win and be applied.
A rule in utilities
would be applied even if it has lower specificity than the rule in theme
. This is because once the layer order has been established, specificity and order of appearance are ignored. This enables the creation of simpler CSS selectors because you do not have to ensure that a selector will have high enough specificity to override competing rules; all you need to ensure is that it appears in a later layer.
Note: Having declared your layer names, thus setting their order, you can add CSS rules to the layer by re-declaring the name. The styles are then appended to the layer and the layer order will not be changed.
The third way is to create an unnamed layer using a @layer
block at-rule without including a layer name. For example:
@layer {
p {
margin-block: 1rem;
}
}
This creates an anonymous cascade layer. This layer functions in the same way as named layers; however, rules cannot be assigned to it later. The order of precedence for anonymous layers is the order in which layers are declared, named or not, and lower than the styles declared outside of a layer.
Another way to create a cascade layer is by using @import
. In this case, the rules would be in the imported stylesheet. Remember that the @import
at-rule must precede all other types of rules, except @charset
and @layer
rules.
@import "theme.css" layer(utilities);
Nesting layers
Layers may be nested. For example:
@layer framework {
@layer layout {
}
}
To append rules to the layout
layer inside framework
, join the two names with a .
.
@layer framework.layout {
p {
margin-block: 1rem;
}
}
Formal syntax
Examples
Simple example
In the following example, two CSS rules are created. One for the <p>
element outside of any layer and one inside a layer named type
for .box p
.
Without layers, the selector .box p
would have the highest specificity, and therefore, the text Hello, world!
will display in green. As the type
layer comes before the anonymous layer created to hold non-layer content, the text will be purple.
Also notice the order. Even though we declare the non-layered style first, it's still applied after the layer styles.
HTML
<div class="box">
<p>Hello, world!</p>
</div>
CSS
p {
color: rebeccapurple;
}
@layer type {
.box p {
font-weight: bold;
font-size: 1.3em;
color: green;
}
}
Result
Assigning rules to existing layers
In the following example, two layers are created with no rules applied, then CSS rules are applied to the two layers. The base
layer defines a color
, border
, font-size
, and padding
. The special
layer defines a different color. As special
comes last when the layers were defined, the color it provides is used and the text is displayed using rebeccapurple
. All of the other rules from base
still apply.
HTML
<div class="item">
I am displayed in <code>color: rebeccapurple</code> because the
<code>special</code> layer comes after the <code>base</code> layer. My green
border, font-size, and padding come from the <code>base</code> layer.
</div>
CSS
@layer base, special;
@layer special {
.item {
color: rebeccapurple;
}
}
@layer base {
.item {
color: green;
border: 5px solid green;
font-size: 1.3em;
padding: 0.5em;
}
}
Result
Specifications
Specification |
---|
CSS Cascading and Inheritance Level 5 # layering |
Browser compatibility
BCD tables only load in the browser