CSS cascade layers let you control which groups of author styles take precedence before selector specificity is compared. You create layers with @layer, establish their order, and place resets, themes, components, utilities, or third-party styles into the appropriate layer.
Layers reduce specificity conflicts and make large stylesheets easier to maintain. A low-specificity rule in a higher-priority layer can override a highly specific rule in a lower-priority layer without adding IDs or !important.
Declare the complete layer order near the start of your stylesheet. The first declaration establishes each named layer's position, and reopening a layer later does not move it.
Declare Cascade Layer Order
List layer names in one statement from lowest to highest priority for normal author declarations.
Example:
/* Establish a predictable project-wide order */
@layer reset, base, theme, components, utilities;
Rules outside all layers have higher priority than normal author rules inside layers. Keep intentional overrides inside an ordered layer when you want layer order to manage them.
Add Rules to Named Layers
@layer base {
/* Define element defaults */
body {
font-family: system-ui, sans-serif;
line-height: 1.5;
}
}
@layer components {
/* Component specificity can stay low */
.button {
border: 0;
padding: 0.75rem 1rem;
}
}
@layer utilities {
/* A later layer wins over earlier normal rules */
.hidden {
display: none;
}
}
How Layer Priority Fits the Cascade
The browser first compares relevance, origin, importance, and layer order. It compares selector specificity only among declarations that remain in the same winning origin and layer. Source order resolves a tie after specificity and scoping proximity.
| Normal Author Rule | Relative Priority |
|---|---|
| First declared layer | Lowest layered priority |
| Later declared layer | Higher layered priority |
| Unlayered style | Higher than all layered normal styles |
Important Declarations Reverse Layer Order
For author declarations marked !important, layer priority reverses: important declarations in the first layer outrank important declarations in later layers. This protects foundational important rules from later overrides.
@layer reset, components, utilities;
@layer reset {
/* First layer: highest important-layer priority */
[hidden] {
display: none !important;
}
}
@layer utilities {
/* This later important rule cannot override the reset rule */
.block {
display: block !important;
}
}
Transitions, animations, user styles, and user-agent styles also participate in the complete cascade. Layers organize rules within an origin; they do not replace the other cascade steps.
Import a Stylesheet into a Layer
Use layer() with @import to place third-party CSS at a known low priority. Imports must appear before other style rules except @charset, layer-order statements, and certain related prelude rules.
/* Keep framework rules below local project layers */
@import url("framework.css") layer(vendor);
@layer vendor, theme, components, utilities;
You can use an anonymous layer for CSS that does not need to be reopened, but a named vendor layer is easier to inspect and extend.
Use Nested Layers
A named layer can contain sublayers. Refer to the full name with a dot when declaring their order outside the parent block.
/* Order sublayers inside the components layer */
@layer components.base, components.variants;
@layer components.base {
.alert {
padding: 1rem;
border: 1px solid;
}
}
@layer components.variants {
.alert-danger {
color: #8a1c13;
}
}
Layer names belong to their containing context. Anonymous layers cannot be referenced or appended to later.
Use revert-layer
The revert-layer keyword rolls a property back to the value from a lower-priority layer in the same origin. If no lower layer supplies it, the cascade continues to earlier origins.
@layer theme, components;
@layer theme {
button {
color: #174ea6;
}
}
@layer components {
.plain-button {
/* Ignore this layer's color and use the theme value */
color: revert-layer;
}
}
Build a Practical Layer Structure
<!DOCTYPE html>
<html lang="en">
<head>
<style>
/* Declare layer order before adding rules */
@layer reset, theme, components, utilities;
@layer theme {
:root { --brand: #1769aa; }
.action { background: var(--brand); color: white; }
}
@layer components {
.action { border: 0; padding: 0.75rem 1rem; }
}
@layer utilities {
.warning { background: #b42318; }
}
</style>
</head>
<body>
<button class="action">Save Order</button>
<button class="action warning">Cancel Order</button>
</body>
</html>
Adopt Layers in an Existing Project
- Inventory resets, vendor CSS, design tokens, components, and utilities.
- Declare a stable order before moving rules.
- Place third-party CSS in an early layer.
- Keep unlayered styles to a minimum because they outrank layered normal rules.
- Test important declarations because their layer order reverses.
- Inspect computed styles to confirm the winning origin and layer.
Common Mistakes
- Assuming the last reopened layer becomes highest priority.
- Leaving most application rules unlayered.
- Expecting layers to override user important styles.
- Using important declarations without considering reversed order.
- Creating anonymous layers that later need extension.
- Relying on specificity before checking layer priority.
Conclusion
CSS cascade layers provide an explicit priority system for groups of styles. Declare order early, isolate third-party rules, keep application styles in intentional layers, account for reversed important priority, and use revert-layer when a component should fall back. This structure reduces specificity battles while preserving the full cascade.