{
    "slug": "css_cascade_layers",
    "term": "CSS Cascade Layers (@layer)",
    "category": "frontend",
    "difficulty": "intermediate",
    "short": "CSS @layer lets you explicitly define the order in which style groups are applied in the cascade — styles in a later layer always win over earlier ones regardless of specificity, eliminating specificity wars in large codebases.",
    "long": "The CSS cascade determines which rule wins when multiple rules target the same element. Before cascade layers, specificity (ID > class > element) and source order determined the winner — leading to escalating specificity arms races in large teams. @layer (introduced in 2022, supported in all modern browsers) adds a new cascade dimension above specificity: a rule in a later-declared layer wins over all rules in earlier layers, regardless of how specific those earlier rules are. Typical usage: @layer reset, base, components, utilities — utilities always win over components which always win over base, without any need for !important or high-specificity selectors. Third-party CSS can be wrapped in a named layer to ensure your own styles always override it. Unlayered styles (those outside any @layer) have the highest priority — a useful escape hatch. Layers interact with @import and can be nested.",
    "aliases": [],
    "tags": [
        "css",
        "cascade",
        "specificity",
        "frontend",
        "design-system"
    ],
    "misconception": "A higher-specificity selector in an earlier layer does NOT win over a lower-specificity rule in a later layer — layer order trumps specificity entirely.",
    "why_it_matters": "Cascade layers eliminate specificity wars in large codebases and design systems — you can integrate third-party CSS without fearing it will override your components, and utilities are guaranteed to win without !important.",
    "common_mistakes": [
        "Declaring layers in the wrong order — the last declared layer has highest priority; @layer reset, utilities gives utilities the win, not reset.",
        "Mixing layered and unlayered styles unintentionally — styles outside any @layer have higher priority than all layered styles.",
        "Wrapping everything in a layer including utility overrides — unlayered utilities have highest priority by default, which is usually what you want."
    ],
    "when_to_use": [
        "Use @layer in any codebase with third-party CSS (Tailwind base, Bootstrap reset) — wrap third-party styles in a named layer so your styles always win.",
        "Use layers in design systems to enforce a predictable override hierarchy: reset → base → components → utilities.",
        "Use them when migrating a legacy codebase with high-specificity selectors — wrap legacy CSS in an early layer so new code can override without specificity gymnastics."
    ],
    "avoid_when": [
        "Avoid cascade layers in small single-file stylesheets where specificity is not yet a problem — the added mental model is not worth it.",
        "Do not use layers in projects that must support older browsers (pre-2022) without a PostCSS polyfill."
    ],
    "related": [
        "css_custom_properties",
        "css_has_selector",
        "css_nesting"
    ],
    "prerequisites": [],
    "refs": [
        "https://developer.mozilla.org/en-US/docs/Web/CSS/@layer",
        "https://www.w3.org/TR/css-cascade-5/#layering"
    ],
    "bad_code": "/* Specificity war — escalating selectors to override third-party CSS */\n.card { background: white; }           /* third-party: specificity 0,1,0 */\ndiv.card.override { background: blue; } /* your fix: 0,2,1 — fragile */\n#app div.card { background: blue; }     /* next escalation: 1,1,1 */",
    "good_code": "/* Cascade layers — layer order determines winner, not specificity */\n@layer reset, base, components, utilities;\n\n@layer reset {\n    * { box-sizing: border-box; margin: 0; }\n}\n\n@layer components {\n    .card { background: white; } /* third-party goes here */\n}\n\n@layer utilities {\n    .bg-blue { background: blue; } /* always wins — later layer */\n}",
    "example_note": "The bad example adds increasingly specific selectors to override third-party styles — a brittle arms race. The fix wraps third-party CSS in an early layer; your utility layer always wins regardless of selector specificity.",
    "created": "2026-03-31",
    "updated": "2026-03-31",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/css_cascade_layers",
        "html_url": "https://codeclaritylab.com/glossary/css_cascade_layers",
        "json_url": "https://codeclaritylab.com/glossary/css_cascade_layers.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[CSS Cascade Layers (@layer)](https://codeclaritylab.com/glossary/css_cascade_layers) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/css_cascade_layers"
            }
        }
    }
}