CSS Cascade Layers
What are CSS Cascade Layers?
CSS Cascade Layers provide a way to group styles and control their precedence in the cascade, regardless of specificity. This allows you to organize your styles into logical layers and explicitly control which styles take precedence.
Browser Support
CSS Cascade Layers are supported in modern browsers:
- Chrome 99+
- Firefox 97+
- Safari 15.4+
- Edge 99+
Basic Syntax
Creating Layers
There are several ways to create cascade layers:
/* Method 1: @layer statement */
@layer base;
@layer components;
@layer utilities;
/* Method 2: @layer block */
@layer base {
p { margin: 1em 0; }
a { color: blue; }
}
/* Method 3: @layer with import */
@import url(base.css) layer(base);
Layer Order
The order of layer declarations determines their precedence:
/* Declaring order (lower layers have lower precedence) */
@layer base, components, utilities;
/* Styles in utilities layer take precedence */
@layer utilities {
.button {
padding: 1rem !important;
}
}
/* Styles in base layer have lowest precedence */
@layer base {
.button {
padding: 0.5rem;
}
}
Layer Nesting
Layers can be nested for more granular control:
@layer framework {
@layer base {
/* framework.base */
a { color: blue; }
}
@layer components {
/* framework.components */
.button { background: blue; }
}
}
@layer theme {
@layer components {
/* theme.components */
.button { background: red; }
}
}
Layer Precedence
Basic Precedence Rules
- Unlayered styles take precedence over layered styles
- Later layers take precedence over earlier layers
- Within a layer, normal specificity rules apply
@layer base, components, theme;
/* Lowest precedence */
@layer base {
.button { background: gray; }
}
/* Medium precedence */
@layer components {
.button { background: blue; }
}
/* Highest precedence */
@layer theme {
.button { background: red; }
}
/* Highest precedence (unlayered) */
.button { background: green; }
Specificity Within Layers
@layer components {
/* Lower specificity, but still in components layer */
.button { background: blue; }
/* Higher specificity in same layer */
.nav .button { background: red; }
}
@layer utilities {
/* Takes precedence despite lower specificity */
.button { background: green; }
}
Practical Examples
Component Library Structure
/* Define layer order */
@layer reset, base, components, utilities;
/* Reset layer */
@layer reset {
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
}
/* Base layer */
@layer base {
body {
font-family: system-ui;
line-height: 1.5;
}
a {
color: #0066cc;
text-decoration: none;
}
}
/* Components layer */
@layer components {
.button {
padding: 0.5rem 1rem;
border-radius: 4px;
background: #0066cc;
color: white;
}
.card {
padding: 1rem;
border: 1px solid #ddd;
border-radius: 4px;
}
}
/* Utilities layer */
@layer utilities {
.hidden { display: none !important; }
.flex { display: flex !important; }
.grid { display: grid !important; }
}
Theme System
/* Base theme */
@layer theme.base {
:root {
--color-primary: blue;
--color-text: black;
}
.button {
background: var(--color-primary);
color: white;
}
}
/* Dark theme overrides */
@layer theme.dark {
[data-theme="dark"] {
--color-primary: #66b3ff;
--color-text: white;
}
[data-theme="dark"] .button {
background: var(--color-primary);
color: black;
}
}
Best Practices
1. Declare Layer Order Early
/* ✓ Good - declare order at the start */
@layer reset, base, components, theme, utilities;
/* ✗ Bad - scattered layer declarations */
@layer reset { /* styles */ }
@layer base;
@layer components { /* styles */ }
@layer utilities;
2. Use Meaningful Layer Names
/* ✓ Good - clear purpose */
@layer framework.components, theme.overrides;
/* ✗ Bad - unclear purpose */
@layer layer1, layer2;
3. Group Related Styles
/* ✓ Good - logical grouping */
@layer components {
/* All button styles together */
.button { /* base styles */ }
.button.primary { /* primary styles */ }
.button.secondary { /* secondary styles */ }
}
/* ✗ Bad - scattered styles */
@layer components {
.button { /* styles */ }
}
@layer theme {
.button { /* more styles */ }
}
4. Use Layers for Specificity Management
/* ✓ Good - explicit layering */
@layer framework, theme;
@layer framework {
.button { background: blue; }
}
@layer theme {
/* Takes precedence without specificity hacks */
.button { background: red; }
}
/* ✗ Bad - specificity wars */
.theme .button { background: red !important; }
Common Use Cases
- Component Libraries: Organizing base styles, components, and utilities
- Theme Systems: Managing default and custom theme styles
- Third-party Integration: Controlling precedence of external styles
- Progressive Enhancement: Layering basic and enhanced styles
- Feature Toggles: Managing feature-specific styles
Debugging Tips
- Use browser dev tools to inspect layer order
- Add comments to indicate layer boundaries
- Use consistent naming conventions
- Keep layer structure documentation updated
CSS Cascade Layers provide a powerful way to manage style precedence and organize large CSS codebases. They're particularly valuable for design systems, component libraries, and applications with complex styling needs.