Master the two new cascade criteria - layers and scope proximity - to architect your styles without specificity wars.
Open this lesson in KodokonThe cascade resolves conflicting declarations using ordered criteria: origin and importance, then context, then style attribute styles, then layers (@layer), then specificity, then order of appearance. The crucial point: layers are evaluated before specificity. A .button rule in a higher-priority layer therefore beats #nav div.menu a.button in a lower-priority layer - its specificity of (1,2,2) counts for nothing against layer order. That is what makes @layer so powerful for architecting a design system: priority is declared once, structurally, instead of being fought for selector by selector.
@layer reset, base, components, utilities;
@layer components {
.button { background: rebeccapurple; }
}
@layer base {
button { background: gray; }
}Two spec subtleties you absolutely need to know. One: styles outside any layer win against layered styles (for normal declarations) - they form an implicit layer placed last. Your local overrides therefore always beat the layered library. Two: with !important, the order fully inverts. The first layers declared win, and an !important inside a layer beats an !important outside any layer. An !important declaration in your reset layer becomes almost unbeatable.
@layer base, theme;
@layer base {
a { color: black !important; }
}
@layer theme {
a { color: purple !important; }
}@scope bounds a set of rules between a scoping root and an optional lower boundary: @scope (.card) to (.card__content) targets elements that are descendants of .card but outside .card__content - the famous donut scope, ideal for styling a component's frame without leaking into its injected content. Inside, :scope refers to the root itself. And @scope introduces a brand-new cascade criterion: proximity. At equal specificity, the rule whose scoping root is closest to the element wins - something neither BEM nor combinators could ever express.
@scope (.card) to (.card__content) {
:scope {
padding: 1rem;
border: 1px solid oklch(0.85 0.02 260);
}
img { border-radius: 8px; }
}