Kaskade

Ein besonderes Merkmal von CSS ist die Kaskade, das C in CSS steht für cascading (englisch für kaskadierend). Ein Dokument kann nicht nur von einem einzelnen Stylesheet formatiert werden, sondern von einer Vielzahl von Stylesheets, die aus verschiedenen Quellen stammen können und aufeinander aufbauen.

Gleichzeitig entsteht aber das Problem, dass Eigenschaften für ein Element mehrfach und mit widersprüchlichen Werten festgelegt werden können. Dieses Problem wird umgangen, indem die Kaskade für Regeln und Eigenschaften eine Gewichtung oder Spezifität errechnet, anhand derer die tatsächlich für ein Element geltenden Formate bestimmt werden.

Kriterien

Herkunft

Ein Stylesheet kann aus drei Quellen stammen:

Beachte: Formate in Browser- und Benutzer-Stylesheets können von den Werten abweichen, die man üblicherweise vorfindet oder die in Webstandards genannt werden. Spezifische Einstellungen des Betriebssystems wie „hoher Kontrast“ oder „dunkles Thema“ können hier Auswirkungen zeigen. Gehe also nicht davon aus, dass die Hintergrundfarbe immer weiß und die Schriftfarbe immer schwarz ist, oder dass 1em gleich 16px ist.

Reihenfolge

Wird eine Eigenschaft oder ein Regelsatz mehrfach deklariert, so wird die zuletzt deklarierte Eigenschaft verwendet.

h1 { color: red; }
h1 {
 color: orange;
 color: green;
}

In diesem Beispiel wird die color-Eigenschaft drei mal innerhalb von zwei Regelsätzen deklariert. Der Wert orange im zweiten Regelsatz überschreibt dabei den Wert red aus dem ersten Regelsatz. orange wird jedoch schon in der nächsten Zeile mit dem Wert green überschrieben, da diese Deklaration als letztes notiert wurde.

Spezifität

In CSS werden Regelsätze nach ihrer Spezifität gewichtet. Allgemeine Regelsätze besitzen dabei eine geringere Gewichtung als spezifische Regelsätze.

Die Spezifität wird durch die Betrachtung der Bestandteile eines Selektors ermittelt. Für jeden Selektor werden drei Zähler (A, B und C) mit dem Startwert Null festgelegt. Jeder Bestandteil eines Selektors wirkt sich auf diese Zähler aus:

*              /* A=0, B=0, C=0, Spezifität 0 0 0 */
h1             /* A=0, B=0, C=1, Spezifität 0 0 1 */
ul li          /* A=0, B=0, C=2, Spezifität 0 0 2 */
a::after       /* A=0, B=0, C=2, Spezifität 0 0 2 */
p:first-child  /* A=0, B=1, C=1, Spezifität 0 1 1 */
a:not([href])  /* A=0, B=1, C=1, Spezifität 0 1 1 */
ul.nav [href]  /* A=0, B=2, C=1, Spezifität 0 2 1 */
#author        /* A=1, B=0, C=0, Spezifität 1 0 0 */
#editor p      /* A=1, B=0, C=1, Spezifität 1 0 1 */

Beachte: Die Zähler der Spezifität sind voneinander unabhängig. Ein hoher Wert des Zählers C wirkt sich nicht auf den Zähler B aus (z. B. ist 0 0 15 weniger spezifisch als 0 1 5).

Spezifität des style-Attributs

Werden Eigenschaften in einem style-Attribut festgelegt, so ist diese Eigenschaft spezifischer als jeder Regelsatz in einem Stylesheet (Regeln innerhalb von style-Attributen können nur durch die Verwendung von !important überschrieben werden). Die Errechnung der Spezifität erfolgt mit Hilfe eines vierten Zählers (hier A), der sich um eins erhöht, wenn ein style-Attribut gesetzt wurde.

*              /* A=0, B=0, C=0, D=0, Spezifität 0 0 0 0 */
h1             /* A=0, B=0, C=0, D=1, Spezifität 0 0 0 1 */
ul li          /* A=0, B=0, C=0, D=2, Spezifität 0 0 0 2 */
a::after       /* A=0, B=0, C=0, D=2, Spezifität 0 0 0 2 */
p:first-child  /* A=0, B=0, C=1, D=1, Spezifität 0 0 1 1 */
a:not([href])  /* A=0, B=0, C=1, D=1, Spezifität 0 0 1 1 */
ul.nav [href]  /* A=0, B=0, C=2, D=1, Spezifität 0 0 2 1 */
#author        /* A=0, B=1, C=0, D=0, Spezifität 0 1 0 0 */
#editor p      /* A=0, B=1, C=0, D=1, Spezifität 0 1 0 1 */
style=""       /* A=1, B=0, C=0, D=0, Spezifität 1 0 0 0 */

!important

Wird eine Eigenschaft mehrfach deklariert, so gilt in der Regel der zuletzt festgelegte Wert. Da dies auch unabsichtlich geschehen kann, existiert die Möglichkeit, einen bestimmten Wert als wichtig zu kennzeichnen. In diesem Fall wird der Wert einer Eigenschaft nicht durch eine nachfolgende Deklaration mit identischer Gewichtung überschrieben.

Ein Wert wird als wichtig gekennzeichnet, indem nach dem Wert selbst optional ein Leerzeichen, ein Ausrufezeichen (!) sowie das Schlüsselwort important notiert werden.

h1 { color: green !important; }
h1.main { color: red; }

In diesem Beispiel wurde der Wert green als wichtig gekennzeichnet. Aus diesem Grund zeigt die nachfolgende Deklaration, die aufgrund des Klassenselektors eigentlich eine höhere Spezifität hätte, keine Auswirkung. Das bedeutet, dass die Schriftfarbe grün dargestellt wird.

Wird eine shorthand-Eigenschaft als wichtig gekennzeichnet, so gilt die Kennzeichnung für alle Untereigenschaften der Kurzschreibweise

border-left: medium double black !important;
/* ... ist identisch zu: */
border-left-width: medium !important;
border-left-style: double !important;
border-left-color: black !important;

Beachte: Verwende !important nur in Ausnahmefällen. Auch wenn man nur wenige !important einsetzt und damit die normale Reihenfolge von Regeln und Deklarationen aussetzt, erschwert es das Zurechtfinden im Stylesheet.

Ablauf der Kaskade

Der Ablauf der Kaskade besteht aus mehreren Schritten, in denen die einzelnen Kriterien angewandt werden und zur Aussortierung von Deklarationen führen.

Im ersten Schritt werden alle Deklarationen gesucht, die unter Berücksichtigung des aktuellen Ausgabemediums auf ein Element angewendet werden. Anschließend werden diese Deklarationen nach Herkunft und Wichtigkeit sortiert:

Diese Sortierung soll sicherstellen, dass Autoren größtmöglichen Gestaltungspielraum haben, aber für den Benutzer wichtige Formate, z. B. die Mindestschriftgröße immer mit Vorrang behandelt werden. Die nun übrigen Regelsätze werden nach ihrer Spezifität geordnet. Regelsätze mit hoher Spezifität überschreiben die mit geringerer Spezifität. Sind am Ende noch widersprüchliche Deklarationen vorhanden, wird die Reihenfolge beachtet. Später deklarierte Eigenschaften überschreiben früher deklarierte.