@layer in CSS: Kaskadenebenen statt !important-Wettrüsten
Irgendwann steht in jedem gewachsenen Stylesheet das erste !important – und ein halbes Jahr später das dreißigste. Mit @layer legst du die Reihenfolge einmal fest, und ab da gewinnt nicht mehr der längste Selektor, sondern die Ebene, die du bestimmt hast.
Es fängt immer gleich an: Du bindest ein fremdes Stylesheet ein, dessen Knopf-Regel als .card .btn.primary geschrieben ist. Deine eigene Regel heißt .btn und verliert. Also schreibst du .card .btn.primary nach – und in der nächsten Datei nochmal, und irgendwann steht dort !important. Danach ist jede weitere Änderung ein Wettrüsten.
@layer löst das an der Wurzel: Du erklärst dem Browser einmal, in welcher Reihenfolge deine Ebenen gelten, und ab da entscheidet die Ebene, nicht die Selektorlänge.
Die Reihenfolge zuerst festlegen
/* GANZ OBEN in der Datei, vor allen Regeln:
die Reihenfolge, in der die Ebenen gewinnen. Später = stärker. */
@layer reset, basis, komponenten, seiten;
@layer reset {
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; }
}
@layer basis {
/* absichtlich sehr spezifisch geschrieben … */
html body .karte .knopf.primaer { background: #999; }
}
@layer komponenten {
/* … und trotzdem gewinnt diese eine Klasse. */
.knopf { background: var(--akz); color: #fff; }
}Der Knopf ist am Ende blau. Nicht, weil .knopf spezifischer wäre – es ist das genaue Gegenteil –, sondern weil komponenten nach basis deklariert wurde. Innerhalb einer Ebene gilt die normale Kaskade weiter; zwischen Ebenen zählt nur die Reihenfolge.
Fremden Code direkt in eine Ebene laden
@layer reset, fremd, komponenten;
@import url("normalize.css") layer(reset);
@import url("kalender-widget.css") layer(fremd);Damit liegt fremdes CSS von Haus aus unter deinem – ganz gleich, wie die Selektoren dort geschrieben sind. Das ist für mich der stärkste Grund, @layer überhaupt zu benutzen.
Zwei Regeln, die man kennen muss
Nicht zugeordnetes CSS gewinnt gegen jede Ebene. Alles, was du außerhalb eines @layer schreibst, hat höhere Priorität als alles darin. Das klingt verkehrt herum, ist aber praktisch: Deine paar Sonderfälle ganz unten in der Datei schlagen weiterhin durch, ohne dass du dafür eine eigene oberste Ebene brauchst. Umgekehrt heißt es: Solange du nicht alles in Ebenen legst, ist die Ordnung nur halb da.
Bei !important dreht sich die Reihenfolge um. Eine wichtige Deklaration in der ersten Ebene schlägt eine wichtige Deklaration in der letzten. Das ist bewusst so gebaut – ein Reset, der etwas erzwingen muss, soll nicht von einer späteren Komponente ausgehebelt werden. In der Praxis ist es vor allem ein Grund mehr, !important gar nicht erst zu brauchen.
Lohnt sich das für kleine Seiten?
Für eine Landingpage mit 200 Zeilen CSS: eher nicht. Sobald aber fremder Code dazukommt oder das Stylesheet über Monate wächst, ist die Ebenen-Deklaration in Zeile 1 die billigste Architekturentscheidung, die es gibt – vier Wörter, die dir später hundert !important ersparen. Ich setze sie inzwischen in jedem neuen Projekt, auch wenn anfangs nur zwei Ebenen darin stehen.
Und falls dein bestehendes Stylesheet schon im Wettrüsten steckt und du nicht weißt, wo man anfängt zu entwirren: Schreib mich über bymw.de an, so etwas räume ich gern auf.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
Verschachteltes CSS – ganz ohne Sass, direkt im Browser
Das Feature, für das die meisten Leute überhaupt erst einen CSS-Präprozessor eingerichtet haben, kann der Browser inzwischen selbst. Kein Build-Schritt, keine Abhängigkeit – nur ein paar Regeln, die man kennen sollte.
Tooltips ohne JavaScript – CSS Anchor Positioning
Ein Tooltip an einen Button hängen, der ausweicht, wenn oben kein Platz ist, und nicht am overflow: hidden der Elternbox scheitert – das brauchte jahrelang eine Bibliothek. Seit Firefox 147 kann das jeder große Browser in reinem CSS.
Schöne Zeilenumbrüche in CSS – text-wrap balance und pretty
Eine Überschrift, bei der ein einzelnes Wort einsam in der letzten Zeile hängt, sieht unruhig aus. Mit text-wrap balance und pretty überlässt du dem Browser das saubere Umbrechen – ohne manuelle <br> und ohne JavaScript.