mitmario.dev

@layer und !important

CSS Im Browser 4 Min Lesezeit 3 BeispieleLektion 4 von 6

Bis hierher hast du Konflikte über die Spezifität gelöst, also über den Selektor. Das funktioniert, führt aber zu Stylesheets, in denen jede neue Regel stärker sein muss als alle bisherigen. @layer dreht den Spieß um: du legst die Rangfolge selbst fest, einmal, ganz oben.

Die Reihenfolge einmal festlegen

Eine einzige Zeile bestimmt, welche Gruppe von Regeln über welcher steht.

Danach ist es völlig egal, wo die Regeln stehen und wie stark ihre Selektoren sind. Ein späterer Layer schlägt einen früheren, immer. Innerhalb eines Layers gilt weiter alles, was du in 3.1 und 3.2 gelernt hast.

Die Reihenfolge steht oben
/* 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 Stärke wie die weiße. Trotzdem gewinnt Gelb, weil utilities in der Deklarationszeile hinter komponenten steht.

Tausch die beiden Namen in der ersten Zeile und die Seite wird weiß, ohne dass du eine Regel angefasst hast. Genau das ist der Punkt: die Rangfolge liegt an einer Stelle und nicht verteilt über die ganze Datei.

Der Reiter „Regeln” schreibt beim Layer mit. Zeig auf die Karte: Oben steht .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; die Spezifität ist hier also gar nicht gefragt, entschieden hat die Stufe darüber.

Und noch etwas siehst du dort: Von der verlierenden Regel ist 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.

Die üblichen vier Layer sind reset, basis, komponenten, utilities, und zwar in dieser Reihenfolge. Ein Reset soll von allem überschreibbar sein, eine Utility-Klasse soll alles überschreiben.

Ein Layer lässt sich mehrfach öffnen. Schreibst du an zwei Stellen @layer utilities { ... }, landen beide Blöcke im selben Layer. Du musst deine Datei also nicht am Stück sortieren.

Ungelayerte Regeln stehen oben drauf

Jetzt die Stelle, an der alle einmal stolpern.

Ohne Layer steht über allen Layern
@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.

Der Grund: Regeln außerhalb jedes Layers bilden selbst eine Gruppe, und die steht über allen benannten Layern. Das klingt verkehrt herum, ist aber praktisch: du kannst eine Bibliothek in einen Layer packen und deine eigenen Regeln unlayered darüberlegen, ohne ihre Selektoren zu kennen.

Für dein eigenes Stylesheet heißt es: entweder du sortierst alles in Layer oder 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.

Wenn important dazwischenfunkt
@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 das ist kein Fehler: Sortiert wird nach der Stärke 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. Dieselbe Ansicht zeigen echte Entwicklerwerkzeuge auch.

Unter mehreren wichtigen Deklarationen dreht sich die Layer-Reihenfolge um: dann gewinnt der früheste Layer, und ungelayerte wichtige Regeln verlieren gegen gelayerte. Das ist kein Kuriosum, sondern Absicht, denn so kann ein Reset etwas wirklich festnageln.

Im Alltag gilt trotzdem: !important ist kein Werkzeug, sondern ein Symptom. Wenn du eines brauchst, gewinnt woanders eine Regel, die du nicht auf dem Schirm hattest. Der Verursacher steht meistens drei Zeilen weiter oben, und ihn zu finden dauert kürzer als der Ärger, den ein !important in drei Monaten macht.

Die Ausnahme sind Utility-Klassen in fremden Frameworks und Stellen, an denen du fremdes Markup mit Inline-Styles überschreiben musst. Gegen ein style-Attribut kommst du sonst nicht an.

Was du davon hast

Layer lösen ein Problem, das mit jedem Projekt größer wird: die Frage, 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. Du kannst .karte schreiben statt main .inhalt .karte, weil die Rangfolge nicht mehr am Selektor hängt. Lektion 16.1 nimmt diesen Faden noch einmal auf, wenn es um den Aufbau einer ganzen Stylesheet-Datei geht.

Zum Mitnehmen

Regeln ohne Layer stehen über allen Layern. Das überrascht beim ersten Mal jeden und erklärt die meisten Fälle, in denen eine Layer-Sortierung scheinbar nichts tut.

Jetzt du

Basis Konto, kostenlos

Zu 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.