Beherrsche die zwei neuen Kaskadenkriterien - Layers und Scope-Nähe -, um deine Stile ohne Spezifitäts-Kriege zu strukturieren.
Diese Lektion in Kodokon öffnenDie Kaskade löst widersprüchliche Deklarationen anhand geordneter Kriterien auf: Ursprung und Wichtigkeit, dann Kontext, dann Stile aus dem style-Attribut, dann Layers (@layer), dann Spezifität, dann Reihenfolge des Auftretens. Der entscheidende Punkt: Layers werden vor der Spezifität ausgewertet. Eine .button-Regel in einem Layer mit höherer Priorität schlägt daher #nav div.menu a.button in einem Layer mit niedrigerer Priorität - ihre Spezifität von (1,2,2) zählt nichts gegen die Layer-Reihenfolge. Genau das macht @layer so mächtig, um ein Designsystem zu strukturieren: Die Priorität wird einmal, strukturell festgelegt, statt Selektor für Selektor erkämpft zu werden.
@layer reset, base, components, utilities;
@layer components {
.button { background: rebeccapurple; }
}
@layer base {
button { background: gray; }
}Zwei Feinheiten der Spezifikation, die du unbedingt kennen musst. Erstens: Stile außerhalb jedes Layers gewinnen gegen Stile in Layers (bei normalen Deklarationen) - sie bilden einen impliziten Layer, der zuletzt einsortiert wird. Deine lokalen Overrides schlagen daher immer die in Layers verpackte Bibliothek. Zweitens: Mit !important kehrt sich die Reihenfolge vollständig um. Die zuerst deklarierten Layers gewinnen, und ein !important innerhalb eines Layers schlägt ein !important außerhalb jedes Layers. Eine !important-Deklaration in deinem reset-Layer wird nahezu unschlagbar.
@layer base, theme;
@layer base {
a { color: black !important; }
}
@layer theme {
a { color: purple !important; }
}@scope begrenzt eine Menge von Regeln zwischen einer Scoping-Root und einer optionalen unteren Grenze: @scope (.card) to (.card__content) zielt auf Elemente, die Nachfahren von .card, aber außerhalb von .card__content sind - der berühmte Donut-Scope, ideal, um den Rahmen einer Komponente zu gestalten, ohne in ihren eingefügten Inhalt überzulaufen. Innerhalb verweist :scope auf die Root selbst. Und @scope führt ein brandneues Kaskadenkriterium ein: Nähe. Bei gleicher Spezifität gewinnt die Regel, deren Scoping-Root dem Element am nächsten ist - etwas, das weder BEM noch Kombinatoren je ausdrücken konnten.
@scope (.card) to (.card__content) {
:scope {
padding: 1rem;
border: 1px solid oklch(0.85 0.02 260);
}
img { border-radius: 8px; }
}