Abschnitt 3 · Lektion 4
@layer und !important
Mit Spezifität allein bekommst du irgendwann Stylesheets, in denen jede neue Regel mehr Gewicht braucht als alle bisherigen. @layer dreht den Spieß um. Die Rangfolge steht einmal ganz oben, und dort legst du sie selbst fest.
Die Reihenfolge einmal festlegen
Eine einzige Zeile bestimmt, welche Gruppe von Regeln über welcher steht. Sie kündigt die Layer nur an und hat keinen Block. Im Kurs heißt sie deshalb Deklarationszeile.
Danach ist es egal, wo die Regeln stehen und welche Spezifität ihre Selektoren haben. Ein späterer Layer schlägt einen früheren, solange kein !important im Spiel ist. Innerhalb eines Layers gilt weiter alles aus den beiden Lektionen davor.
<div class="karte hervorgehoben">Welche Farbe gewinnt?</div> /* Diese eine Zeile legt die Reihenfolge fest.
Wo die Blöcke danach stehen, ist egal. */
@layer komponenten, utilities;
@layer utilities {
.hervorgehoben {
background-color: #fef9c3;
}
}
@layer komponenten {
.karte {
background-color: #ffffff;
padding: 16px;
border: 1px solid #d4d4d8;
}
} Die gelbe Regel steht hier weiter oben in der Datei und hat dieselbe Spezifität wie die weiße. Trotzdem gewinnt Gelb, weil utilities in der Deklarationszeile hinter komponenten steht.
Stehen die beiden Namen in der ersten Zeile andersherum, wird die Seite weiß, ohne dass sich eine Regel ändert. Die Rangfolge liegt an einer Stelle und nicht über die ganze Datei verteilt.
Im Reiter „Regeln“ steht der Layer mit dabei. An der Karte steht oben .hervorgehoben und darunter klein @layer utilities, das ist die Gewinnerin. Darunter steht .karte mit background-color überstimmt aus @layer utilities · @layer komponenten. Beide haben dieselbe Zahl, 0-1-0. Auf die Spezifität kommt es hier also gar nicht an. Entschieden hat die Stufe darüber.
Von der verlierenden Regel ist dort außerdem nur eine einzige Zeile durchgestrichen. padding und border gelten weiter, es gibt sie in der anderen Regel ja gar nicht. Eine Regel verliert nie als Ganzes, sondern immer Zeile für Zeile, und deshalb steht der Name der Eigenschaft im Vermerk.
Meistens sind es vier Layer, reset, basis, komponenten, utilities, und zwar in dieser Reihenfolge. Ein Reset soll von allem überschreibbar sein, eine Utility-Klasse soll alles überschreiben. So heißt eine kleine Klasse mit einer einzigen Aufgabe, etwa zentriert für zentrierten Text.
Ein Layer lässt sich mehrfach öffnen. Steht an zwei Stellen @layer utilities { ... }, landen beide Blöcke im selben Layer, und die Datei muss nicht am Stück sortiert sein.
Regeln ohne Layer stehen oben drauf
<div class="karte hervorgehoben">Diesmal gewinnt Weiß.</div> @layer komponenten, utilities;
@layer utilities {
.hervorgehoben {
background-color: #fef9c3;
}
}
/* Diese Regel steht in keinem Layer. Damit steht sie über
allen Layern, egal wie die sortiert sind. */
.karte {
background-color: #ffffff;
padding: 16px;
border: 1px solid #d4d4d8;
} Dieselbe Ausgangslage, nur steht die weiße Regel diesmal in keinem Layer. Und plötzlich gewinnt sie, obwohl utilities doch der letzte Layer ist.
Im Streifen steht jetzt .karte oben, ohne Zeile darunter, denn zu einer Regel ohne Layer gibt es nichts zu vermerken. Die gelbe steht darunter, durchgestrichen, mit überstimmt aus einer Regel ohne Layer · @layer utilities.
Regeln außerhalb jedes Layers bilden nämlich selbst eine Gruppe, und die steht über allen benannten Layern. Das klingt verkehrt herum, ist aber praktisch. Du steckst eine Bibliothek in einen Layer und lässt die eigenen Regeln ohne Layer darüber liegen, und dann musst du die Selektoren der Bibliothek nicht einmal kennen.
Im eigenen Stylesheet sortiere ich deshalb alles in Layer oder gar nichts. Eine halbe Sortierung sieht aus, als hätte @layer keine Wirkung.
Wo !important vertretbar ist
!important hängt sich an eine einzelne Deklaration und hebelt Spezifität und Layer aus.
<div class="karte hervorgehoben">Und jetzt doch wieder Gelb.</div> @layer komponenten, utilities;
@layer utilities {
/* Eine wichtige Deklaration schlägt jede normale,
unabhängig von Layern und Spezifität. */
.hervorgehoben {
background-color: #fef9c3 !important;
}
}
.karte {
background-color: #ffffff;
padding: 16px;
border: 1px solid #d4d4d8;
} Diesmal steht die Gewinnerin unten in der Liste, und zwar mit Absicht. Sortiert wird nach dem Rang der Regel, und !important hängt nicht an der Regel, sondern an der einzelnen Deklaration. Oben steht also weiter .karte, und seine background-color-Zeile ist durchgestrichen mit überstimmt durch !important. In den echten Entwicklerwerkzeugen sieht es genauso aus.
Treffen mehrere wichtige Deklarationen aufeinander, dreht sich die Layer-Reihenfolge um. Dann gewinnt der früheste Layer, und wichtige Regeln ohne Layer verlieren gegen solche in einem Layer. Das ist Absicht, denn so kann ein Reset etwas wirklich festnageln.
Brauche ich ein !important, gewinnt woanders eine Regel, die ich nicht auf dem Schirm hatte. Die zu finden kostet weniger Zeit als der Ärger, den ein !important in drei Monaten macht.
Ausnahmen sind Utility-Klassen in fremden Frameworks und Stellen, an denen fremdes Markup mit Inline-Styles überschrieben werden muss. Gegen ein style-Attribut kommt sonst nichts an.
Was du davon hast
Layer lösen ein Problem, das mit jedem Projekt größer wird. Ob eine neue Regel greift, hängt nicht mehr davon ab, wo sie steht und wie lang ihr Selektor ist.
Damit fällt auch der Anreiz weg, Selektoren künstlich zu verlängern. .karte reicht statt main .inhalt .karte, weil die Rangfolge nicht mehr am Selektor hängt. Beim Aufbau einer ganzen Stylesheet-Datei in Lektion 16.1 kommt das noch einmal dran.
In der Aufgabe stimmt die Rangfolge von drei Gruppen nicht, und keine der bestehenden Regeln darf sich dafür ändern.
Zum Mitnehmen
Eine Zeile @layer legt fest, welche Gruppe gewinnt, egal wo die Regeln stehen und welche Spezifität ihre Selektoren haben. Regeln ohne Layer stehen über allen, und !important dreht die Reihenfolge um.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 3 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.