The StyleWorksCSS { Referenz · Labor · Übungen }
  1. Startseite
  2. Lernen
  3. Kaskade

Grundlegendes

CSS Kaskade: wie Regeln nach Herkunft, Reihenfolge, Spezifität und !important gewichtet werden

Die CSS Kaskade wählt für jedes Element und jede Eigenschaft genau eine Deklaration aus: erst nach Herkunft und !important, dann nach Spezifität der Selektoren, zuletzt nach Reihenfolge im Quelltext. Der Wasserfall in vier Stufen, mit Beispielen und einem Visualizer.

Erstveröffentlichung Lesezeit 5 min

Es passiert immer wieder, dass innerhalb der notierten CSS-Regeln Konflikte auftreten, d. h. dass für eine Eigenschaft eines Elements im Webdokument (=Subjekt) mehrere verschiedene Deklarationen des Stylesheets (oder aus mehreren Stylesheets) zutreffen. Das kann viele verschiedene Gründe haben, es kann Absicht sein oder nicht. Zur Lösung solcher Fälle folgt CSS 2.1 einer exakt vorgegebenen Prozedur, die immer ein eindeutiges Ergebnis hat. Diese Prozedur wird die Kaskade genannt – der Browser führt sie für jede Eigenschaft eines Elements und für alle Elemente eines Dokuments nacheinander aus.

Der Wasserfall

Genau wie das Wasser eines Wasserfalls (engl. 'cascade') laufen auch die Deklarationen eines Stylesheets über mehrere Stufen. Durch diese Stufen werden die letztendlich gültigen (und angewendeten) Deklarationen bestimmt.

Mit Ausnahme des Konstrukts important! innerhalb einzelner Deklarationen gibt dieser Ablauf den Stylesheets des Webautors höheres Gewicht als denen des Benutzers. Deshalb ist es wichtig, dass das Anwenderprogramm dem Leser die Möglichkeit gibt, den Einfluß bestimmter Stylesheets auszuschalten.

Stufe 1:

Finde alle Deklarationen, die für die aktuelle Element/Eigenschaft- Kombination im designierten Medientyp in Frage kommen. Das ist dann der Fall, wenn der der Deklaration zugeordnete Selektor und das aktuelle Element übereinstimmen.

Entscheidung:

  • Gibt es nur eine Deklaration für die aktuelle Element/Eigenschaft- Kombination, wende sie an und gehe weiter zum nächsten Element.
  • Gibt es mehr als eine Deklaration für die aktuelle Element/Eigenschaft- Kombination, gehe weiter nach Stufe 2.

Stufe 2:

Sortiere die gefundenen Deklarationen nach ihrem Ursprung (Stylesheet des Site-Autors, des Nutzers oder des Anwenderprogrammes) und nach ihrer Wichtigkeit. Die Wichtigkeit wird von der Deklaration important! bestimmt. Die folgende Reihenfolge in absteigender Wichtigkeit ist einzuhalten:

  1. Deklarationen des Benutzer- Stylesheets, die die Deklaration important! enthalten.
  2. Deklarationen aus der Website, die die Deklaration important! enthalten.
  3. Deklarationen aus der Website, die nicht die Deklaration important! enthalten.
  4. Deklarationen des Benutzer- Stylesheets, die nicht die Deklaration important! enthalten.
  5. Deklarationen des Anwenderprogrammes (Browser- Stylesheet).

Entscheidung:

  • Gibt es nur Deklarationen unterschiedlicher Wichtigkeit für die aktuelle Element/Eigenschaft- Kombination, wende die Deklaration mit der höchsten Wichtigkeit an und gehe weiter zum nächsten Element.
  • Gibt es mehrere Deklaration mit gleicher Wichtigkeit für die aktuelle Element/Eigenschaft- Kombination, gehe weiter nach 3.

IE/Win 6 erlaubt keine Änderung des User-Stylesheets und kann deshalb hier nur die Werte 'b', 'c' und 'e' unterscheiden. Daher ist es sinnlos, das Konstrukt !important zur Unterscheidung von Autoren- und Anwender- Stylesheets zu verwenden.

Stufe 3:

Sortiere nach der Spezifizität des Selektors.

Entscheidung:

  • Gibt es nur Deklarationen unterschiedlicher Spezifizität für die aktuelle Element/Eigenschaft- Kombination, wende die Deklaration mit der höchsten Spezifizität an und gehe weiter zum nächsten Element.
  • Gibt es mehrere Deklaration mit gleicher Spezifizität für die aktuelle Element/Eigenschaft- Kombination, gehe weiter nach 4.

Stufe 4:

Zum Schluß sortiere nach der Reihenfolge des Auftretens: wenn zwei Regeln das gleiche Gewicht, denselben Ursprung und gleich hohe Spezifizität haben, erhält die zuletzt notierte Regel den Vorrang. Regeln aus dem Stylesheet im Kopf des Dokumentes liegen per Definition 'nach' den Regeln aus importierten Stylesheets und haben deshalb Vorrang.

Beispiele

Beispiel 1

Angenommen, das Anwenderprogramm findet die folgenden Elemente in einem Webdokument, dass nur zur Bildschirmausgabe bestimmt sein soll:

<div id="hauptteil">
   ...
  <div id="kapitel-1">
     ...
    <p class="blau gruen"> ... </p>
     ...
  </div>
   ...
</div>

Der Absatz ist hier Teil des div mit dem ID kapitel-1, dieses wiederum ist Kindelement des div mit dem ID hauptteil. Es geht hier um die Formatierung des Elements p.

Dazu ist eine Deklaration im Stylesheet des Benutzers vorhanden:

P { border:... }                                      /* 1. */

Drei Deklarationen sind im Stylesheet des Webautors vorhanden:

#hauptteil P { border:... }                           /* 2. */
#kapitel-1 P.blau { border:... }                      /* 3. */
#kapitel-1 P.gruen { border:... }                     /* 4. */

Damit wurden in Stufe 1 insgesamt 4 Deklarationen gefunden, die auf das Element zutreffen könnten.

In Stufe 2 findet sich eine Deklaration, die nach ihrer Wichtigkeit unter 'd.' einzuordnen ist (1.). Die 3 anderen Deklarationen sind dagegen unter 'c.' einzuordnen und gehen in die nächste Runde.

Inder dritten Stufe wird festgestellt, dass eine der drei übrig gebliebenen Deklarationen des Beispiels die Spezifizität '0-1-0-1' hat (2.). Sie scheidet damit aus, denn die anderen beiden haben eine Spezifizität von '0-1-1-1'.

In der vierten Stufe erfolgt die Entscheidung, dass die zuletzt notierte der beiden verbliebenen Deklarationen angewendet wird (4.).

Beispiel 2

Wir haben hier dieselbe Grundkonstellation wie im Beispiel 1, mit einem kleinen Unterschied: die Regeln (2.) und (3.) enthalten zusätzlich eine Deklaration zur Definition der Hintergrundeigenschaften. Hier können wir sehen, wie die vier Stufen der Kaskade für jede Element/Eigenschaft- Kombination durchlaufen werden.

Auch hier ist wieder eine Deklaration im Stylesheet des Benutzers vorhanden:

P { border:... }                                      /* 1. */

Diese drei Deklarationen sind im Stylesheet des Webautors vorhanden:

#hauptteil P { border:...; background:... }           /* 2. */
#kapitel-1 P.blau { border:...; background:... }      /* 3. */
#kapitel-1 P.gruen { border:... }                     /* 4. */

Die im Beispiel 1 genannten 4 Stufen werden hier zweimal durchlaufen: zuerst für die Kombination des Elements p mit der Eigenschaft border, d. h. zur Festlegung des Rahmens, mit demselben Ergebnis wie oben.

Danach wird noch der Hintergrund für das Element p als Kombination von p mit background ermittelt.

In Stufe 1 werden insgesamt 2 Deklarationen gefunden, die auf das Element zutreffen könnten.

In der zweiten Stufe scheidet keine der Deklaration aus, da beide nach ihrer Wichtigkeit unter 'c.' einzuordnen sind.

In Stufe 3 fällt hier bereits die Entscheidung, denn die Regel (2.) hat die Spezifizität '0-1-0-1', die Regel (3.) dagegen hat eine Spezifizität von '0-1-1-1'. Die Sortierung nach der Reihenfolge entfällt.

Damit wird für des Element p dieses Beispiels 2 der in Regel (4.) deklarierte Rahmen und der in Regel (3.) deklarierte Hintergrund verwendet.

Stufe 1 der CSS Kaskade – alle Regeln sammeln, die das Element treffen

Die CSS Kaskade beginnt nicht mit dem Gewichten, sondern mit dem Sammeln. Für ein Element und eine Eigenschaft – etwa color für dieses p – werden alle Deklarationen zusammengetragen, deren Selektor das Element trifft und deren Medientyp passt. Aus dem Browser-Stylesheet, aus dem Stylesheet des Nutzers, aus allen Autor-Stylesheets und aus dem style-Attribut. Gibt es nur eine, gilt sie. Gibt es keine, kommt die Kaskade nicht zum Zug: Dann greift die Vererbung, und wenn die Eigenschaft nicht vererbt wird, der Ausgangswert.

Stufe 2 – Herkunft und !important

Die Regeln werden zuerst nach Herkunft geordnet, und !important dreht diese Ordnung um. Ohne !important gilt: Autor schlägt Nutzer schlägt Browser. Mit !important kehrt sich die Ordnung um: Nutzer-Deklarationen mit !important stehen ganz oben, dann Autor-!important, dann die normalen Autor-Deklarationen, dann Nutzer, dann Browser. Das ist der Zweck von !important in der Spezifikation – nicht ein Vorrang für den Autor, sondern ein Vorrang für den Nutzer, der etwa eine größere Schrift braucht. Im Autor-Stylesheet ist !important ein Werkzeug für die Ausnahme, die gegen alles gewinnen muss, nicht für den Alltag: Jede weitere !important-Regel konkurriert nur noch mit anderen !important-Regeln, und die Kaskade verliert ihre Abstufung.

Stufe 3 – Spezifität der Selektoren

Bleiben mehrere Deklarationen derselben Herkunft und Wichtigkeit, entscheidet die Spezifität des Selektors: das Tupel aus Inline-Stil, IDs, Klassen und Typselektoren, von links nach rechts verglichen. #main .text p mit (0,1,1,1) gewinnt gegen .text p mit (0,0,1,1), das gegen p mit (0,0,0,1). Diese Stufe ist die, an der die meisten Stylesheets ihre Probleme haben, weil sie mit immer spezifischeren Selektoren gegen frühere Regeln anrechnen. Flache Selektoren auf einer Ebene halten die Kaskade steuerbar.

Stufe 4 – Reihenfolge im Quelltext

Sind Herkunft, Wichtigkeit und Spezifität gleich, gewinnt die Deklaration, die zuletzt kommt. Innerhalb eines Stylesheets ist das die weiter unten stehende Regel; über mehrere Stylesheets hinweg zählt die Reihenfolge, in der sie eingebunden sind – per @import importierte Stylesheets gelten als vor dem importierenden stehend. Deshalb ist die Reihenfolge der link-Elemente kein Detail: Ein Reset-Stylesheet nach dem Theme setzt das Theme zurück.

Beispiel: vier Regeln in der CSS Kaskade, ein Gewinner

p { color: black; }0,0,0,1Autor
.text p { color: gray; }0,0,1,1Autor
#main .text p { color: #7A2FB0; }0,1,1,1Autor · gewinnt
p { color: navy; }0,0,0,1Browser

Alle vier treffen dasselbe p. Stufe 2 sortiert die Browser-Regel nach unten. Unter den drei Autor-Regeln entscheidet Stufe 3: die ID gewinnt. Stufe 4 wird nicht mehr gebraucht. Stünde p { color: black !important; } im Stylesheet, gewänne diese Regel bereits in Stufe 2, und die Spezifität der ID spielte keine Rolle mehr.

Die CSS Kaskade nach CSS 2.1 – Cascade Layers und Scoping

Die vier Stufen der CSS Kaskade gelten unverändert. CSS Cascading Level 5 schiebt zwischen Herkunft und Spezifität eine weitere Stufe: Cascade Layers, mit @layer deklariert. Regeln in einer späteren Schicht gewinnen gegen frühere Schichten unabhängig von der Spezifität – ein Reset in der ersten Schicht kann von jeder Regel in einer späteren Schicht überschrieben werden, auch von einer weniger spezifischen. Ungeschichtete Regeln stehen über allen Schichten. Damit wird das Problem der Stufe 3, der Wettlauf der Spezifität, an der Wurzel gelöst: Die Ordnung der Schichten ist eine Entscheidung des Autors, nicht eine Folge der Selektoren.

Häufige Fragen

Was ist die Kaskade in CSS?

Der Mechanismus, der für jedes Element und jede Eigenschaft aus allen zutreffenden Deklarationen genau eine auswählt. Er wertet nacheinander Herkunft und !important, dann die Spezifität des Selektors, zuletzt die Reihenfolge im Quelltext.

In welcher Reihenfolge prüft die Kaskade?

Erst Herkunft und Wichtigkeit (Browser, Nutzer, Autor, jeweils mit und ohne !important), dann Spezifität der Selektoren, dann Reihenfolge im Quelltext. Eine spätere Stufe wird nur geprüft, wenn die frühere unentschieden ist.

Was macht !important in der Kaskade?

Es hebt eine Deklaration auf eine höhere Wichtigkeitsstufe. Autor-Regeln mit !important schlagen alle normalen Autor-Regeln; Nutzer-Regeln mit !important schlagen sogar diese. Die Spezifität spielt erst innerhalb derselben Stufe eine Rolle.

Gewinnt immer die letzte Regel?

Nur bei gleicher Herkunft, Wichtigkeit und Spezifität. Eine frühere Regel mit spezifischerem Selektor gewinnt gegen eine spätere mit schwächerem Selektor.

Welche Rolle spielt die Reihenfolge der Stylesheets?

Bei gleicher Spezifität gewinnt die spätere Deklaration – auch über Dateigrenzen. Ein Stylesheet, das nach einem anderen eingebunden ist, überschreibt dessen gleich spezifische Regeln. Per @import importierte Dateien gelten als vor der importierenden stehend.

Was ist der Unterschied zwischen Kaskade und Vererbung?

Die Kaskade wählt unter Deklarationen, die ein Element direkt treffen. Vererbung greift erst, wenn die Kaskade für eine Eigenschaft nichts ergibt, und übernimmt dann den Wert des Elternelements – nur bei vererbbaren Eigenschaften.

Warum gilt meine Regel nicht, obwohl sie weiter unten steht?

Weil eine frühere Regel entweder !important trägt, aus einer höheren Wichtigkeitsstufe stammt oder einen spezifischeren Selektor hat. Die Reihenfolge ist die letzte Stufe der Kaskade und entscheidet nur bei Gleichstand der anderen.

Was sind Cascade Layers?

Eine mit @layer deklarierte Schicht aus CSS Cascading Level 5. Spätere Schichten gewinnen gegen frühere unabhängig von der Spezifität, ungeschichtete Regeln gegen alle Schichten. Sie sitzen in der Kaskade zwischen Herkunft und Spezifität.