CSS Cascading – die CSS-Kaskade

CSS Kaskade, cascading

Die CSS-Kaskade löst Konflikte, wenn Stile für einen Selektor einander überschreiben. Die einfachste Regel lautet: Wer zuletzt kommt, gewinnt. Precedence (Vorrang) und Specifity (Spezifität) sind die komplizierteren Regeln

Cascading Stylesheets – wie ein Wasserfall

Schon mit dem Ändern einer Kleinigkeit wendet sich Cascading ohne jegliche Warnung gegen alles. Selektoren werden länger und komplexer und die Suche nach der Ursache wird zum Blick in einen Abgrund. Obwohl CSS in einzelnen Regeln einfach ist, zeigen Änderungen von CSS-Stilen nicht immer die gewünschte Wirkung. Meist liegt dann eine weitere CSS-Regel für dasselbe Element an anderer Stelle – z.B. im style-Element im Head der HTML-Datei.

CSS-Regeln können aus fünf Quellen kommen:

p { font-size: 16px; }
Der Browser bringt eigene Stile (z.B. Schriftgröße, Farbe und margin für p-Elemente) mit.
p { font-size: 86%; }
Externe CSS-Datei
<style>p { font-size: 86%; }</style>
CSS-Regeln im style-Tag der Webseite
<p style="font-size: larger;">
style-Attribut eines HTML-Tags (CSS Inline)
body { zoom: 90%; }
Stylesheet des Besuchers

CSS Cascading and Inheritance Level 3

CSS-Konflikte zwischen CSS-Dateien und style-Tags lösen

Wenn CSS-Stile in Konflikt geraten, weil sie extern in der CSS-Datei, im style-Tag, in einer inline-Regel und im Stylesheet des Benutzers unterschiedlich deklariert sind, löst die Kaskade den Konflikt. Die Regel, die dem Element am nächsten liegt, hat die höhere Priorität.

CSS Cascade: Überschreiben von CSS-Eigenschaften
Beispiel: Kaskade mit CSS-Eigenschaften, die einander überschreiben
  1. Eine CSS-Eigenschaft überschreibt die vom Browser vorgegebene Eigenschaft.
  2. Führen CSS-Stile zu Konflikten, übertrumpft die Regel, die zuletzt aufgeführt wird, gleich, ob sie aus einer externen CSS-Datei oder einem style-Element im Seitenkopf entspringt.
  3. Eine genauer definierte Stylesheet-Regel überschreibt eine weniger genau deklarierte Regel.
    .post h4 { color: teal; }
    h4 { color: darkorange; }
    
    .post h4 setzt sich durch, obwohl eine Regel an späterer Position ein anderer Stil zugeordnet: .post h4 ist spezifischer als h4.
  4. Ein style-Attribut im HTML-Tag überschreibt eine Eigenschaft aus einer globalen Regel im style-Element des HTML-Dokuments oder aus einer CSS-Datei. Regeln in style-Attributen setzten sich gegen alle anderen Regeln durch.

    <style type="text/css" title="text/css" media="screen">
       h4 { color: teal; }
    </style>
    …
    <body>
       …
       <h4 style="color: darkorange;"> … </h4>
       …
    </body>
    
  5. Ein CSS-Stil aus dem Stylesheet des Besuchers überschreibt die CSS-Stile des Webdesigners.

Precedence – Vorrang

Selektoren haben einen Rang. Das geringste Gewicht haben die vorgegebenen Stile des Browsers, die von Tag-Selektoren wie p oder h2 überschrieben werden. ID-Selektoren haben das höchste Gewicht.

Default Browser-Style Tag-Selektor Direktes Kind-Selektor Nachfolger-Selektor Kind-Selektor class-Selektor Attribut-Selektor ID-Selektor
<h2 id="header" class="entry-title">Precedence</h2>

.entry-title { color: red }
h2 { color: green }

Der class-Selektor .entry-title gewinnt – er hat den Vorrang vor dem Tag-Selektor. Am Ende der Precedence-Kette steht jedoch !important, das auch noch den ID-Selektor übertrumpft.

CSS-Spezifität: Wenn Stile »blockiert« werden

Auch bei zwei Regeln für ein Element innerhalb einer CSS-Datei gilt: Die Letzte bestimmt die Regel. Aber nicht immer …. Die Spezifizität der CSS-Deklarationen ist eine Blockade:

.menu .active { color: blue; } /** Gewinnt **/
.active { color: red; }        /** Verliert, da geringere Spezifität **/

Wenn li.active im CSS erst nach ul.menu li.active steht, wird die Regel li.active {} keine Wirkung zeigen, weil ul.menu li.active genauer spezifiziert ist. Wer am CSS für WordPress arbeitet, weiß ein Lied davon zu singen, denn das CSS für Gutenberg arbeitet mit einer hohen Spezifität.

.entry .entry-content .has-dark-gray-color {
	color: #111;
}

Um diese Regel zu überschreiben, muss das CSS mindestens dieselbe Spezifität aufweisen. Diese Spezifität ist in der Form (l5, l4, l3, l2, l0) festgelegt:

GewichtSelektor
0.0.0.0.0*
0.0.0.0.1Element oder Pseudo-Element
0.0.0.1.0class, pseudo-class oder Attribut-Selektor
0.0.1.0.0ID-Selektor
0.1.0.0.0inline style
1.0.0.0.0!important
SelektorSpezifität
* { }0,0,0,0
div { }0,0,0,1
li:first-line { }0,0,0,2
ul li { }0,0,0,2
ul ol+li { }0,0,0,3
label + *[value="Hinz"] { }0,0,1,1
ul ol li.dark0,0,1,3
li.active.dark0,0,2,1
#myid0,1,0,0
style=""1,0,0,0

Tabelle 2: Beispiele für Spezifität.

  1. Element-Selektoren haben die geringste Spezifität, gefolgt von Klassen und dann ID-Attributen.
  2. Verkettete Selektoren – mehrere Selektoren in einer Regel – addieren die Spezifität der Selektoren. .menu .activ hat eine höhere Spezifität als .active.
  3. !important setzt die Spezifität auf das Maximum.
  4. inline-Stile überschreiben alle anderen Regeln.

Eine Faustregel: Je spezifischer und komplexer der Selektor, desto später sollte die Regel im Stylesheet erscheinen.

Leitfaden für den Einsatz von Selektoren

  1. Am besten wählt man bei jeder Regel die geringste Spezifität – idealerweise eine einzelne Klasse, denn Klassen-Selektoren lassen sich am einfachsten ändern.
  2. IDs nur benutzen, wenn es absolut nötig ist, denn es ist immer schwierig, ID-Selektoren zu überschreiben.
  3. Inline-Stile vermeiden
  4. !Important möglichst nur in höchster Not benutzen, z.B. um Stile aus externen Stylesheets bei WordPress-Themes zu überschreiben.

  5. Die generellen Regeln der Kaskade beachten:

    Inline-Stile überschreiben Selektoren mit ID-Attribut
    Selektoren mit ID-Attribut überschreiben Selektoren mit CSS-class-Attribut
    Selektoren mit CSS-class-Attribut überschreiben Element-Selektoren.

CSS !IMPORTANT-Regel

Diese Regeln können wiederum vom Autor durch das Schlüsselwort !IMPORTANT außer Kraft gesetzt werden.

li { margin: 0 !IMPORTANT; }
…
.featured li { margin: 4px 0; }

Am Ende hat der Besucher wieder die Oberhand, denn er kann auch wieder eine !important-Regel in sein persönliches Stylesheet legen.

CSS zurücksetzen: revert und unset

Beim Anpassen von Themes für WordPress oder andere Content Management Systeme liegen die CSS-Dateien in ganzen Stapeln übereinander und für ein individuelles Themes werden Stile überschrieben.

revert und unset setzen Stile zurück auf die Standard-Browser-Darstellung (revert) oder nehmen einen Stil komplet weg (unset).

H1: revert oder unset?

 
color:revert
font-size:revert
font-weight:revert
color:unset
font-size:unset
font-weight:unset

color:revert und color:unset haben dieselbe Wirkung: Die Browser setzen Schwarz als Standardfarbe bei Text. font-size:revert setzt die Schriftgröße auf den Standardwert der Browser, font-size:unset auf die Standard-Schriftgröße überhaupt: 1em.

revert ist eine relativ junge Eigenschaft, wird aber von allen immergrünen Browsern unterstützt (nicht IE).

Neben CSS revert und unset gibt es noch die Werte inherit und initial, um CSS-Eigenschaften zurückzusetzen (CSS reset).

CSS in der Browser-Konsole untersuchen

Wer Javascript programmiert kennt die Browser-Konsole, die sich mit einem Rechtsklick und Element untersuchen oder Element-Informationen unter oder neben dem Dokument öffnet.

Hier zeigen die Browser, welche CSS-Stile auf jedes einzelne Element wirken.

CSS in der Browser-Console untersuchen

Wenn die CSS-Regeln aus einem halben Dutzend CSS-Dateien stammen, die Eigenschaften eines Elements immer wieder überschreiben (klassischer Fall von Content Management System wie WordPress), oder Eigenschaften bei bestimmten Breakpoints prüfen wollen, hilft Javascript mit getComputedStyle.



const elem = document.querySelectorAll ("h2")[0];
const allStyles  = window.getComputedStyle (elem);
	
document.querySelector("#h2Styles").textContent =
`font-size ${allStyles.getPropertyValue("font-size")}`;