CSS Nesting – CSS-Regeln verschachteln

Nesting

Bis Ende 2023 gab es Nesting – das Verschachteln von CSS-Regeln – nur mit Präprozessoren wie SASS und LESS, aber im letzten Quartal 23 haben alle Mainstreambrowser CSS Nesting umgesetzt. Das Verschachteln der CSS-Regeln hält die Stile zusammengehöriger Layout-Blöcke zusammen.

23-02-02 SITEMAP

CSS nesting – verschachteln

Statt einen Selektor wiederholt mit verschiedenen Kind-Elementen oder Pseudo-Selektoren zu notieren, setzt das native CSS Nesting eine untergeordnete Regel in eine übergeordnete Regel.

header {
	background: ivory;
	& h1 { 
		font-size: 2.2rem
	}
}

Dabei entsteht eine übersichtliche Hierarchie, die besser lesbar und einfacher zu ändern ist.

<header>
	<h1>Header</h1>
	<p>Ein Absatz im header-Element <a href="post.html">mit einem Link</a></p>
</header>

Das CSS für dieses Beispiel ist schlicht und einfach, aber CSS-Regeln für komplexere Strukturen verteilen sich kreuz und quer über die gesamte CSS-Datei, je nachdem an welcher Stelle des Layouts und mit welcher Media Query die Struktur eingesetzt wird. Die Selektoren werden länger und länger.

CSS-Regeln verschachteln

Mit CSS Nesting ändert sich die Schreibweise wie folgt: Die Kind-Elemente werden unterhalb des Eltern-Elements eingetragen.

main header {
	background: #efefef;
	margin: auto;
	padding: 1rem;
	p {
		font-size: 1.2rem;
		background: ivory;
		padding: 1rem;
		
		a { text-decoration: none; }
	}
}

Klassen- und id-Selektoren werden mit einem führenden & eingesetzt.

a {
	text-decoration: none; 
	&:hover {
		color: darkorange;
	}
}

Nesting macht das CSS modularer, spiegelt die inhaltlichen Zusammenhänge besser wieder und hält die Regeln der Strukturen zusammen.

Nesting und @media-Regeln

@media-Queries können direkt in die CSS-Regeln eines Selektors gesetzt werden.

body {
	font-size: 1.1em;
	
	@media (max-width: 700px) {
		& { background: ivory; }
	}
	
	@media (max-device-width: 480px) {
		& { -webkit-text-size-adjust: 100% }
	}
}

Das & vor dem Selektor

Wie schon die Regel a:hover gezeigt hat, brauchen einige Regeln und auch einige ältere Browser ein führendes & (Safari 16.5, Chrome und Edge 112-119). Da die jüngere Browsergeneration die &-Schreibweise auch weiterhin unterstützt, kann man einfach dabei bleiben.

Das führende & ist sozusagen die Referenz auf den übergeordneten Selektor und verbessert zudem die Lesbarkeit.

main header {
	background: #efefef;
	margin: auto;
	padding: 1rem;
	margin: 0.5rem;
	& p {
		font-size: 1.2rem;
		background: ivory;
		padding: 1rem;
		
		& a { // Leerzeichen: Unterordnung
			text-decoration: none; 
			&:hover {  // kein Leerzeichen: Klasse, Klassen- oder Pseudo-Selektor
				color: darkorange
			}
		}
	}
}

Wichtig:Klassen-, id-, Attribut- und Pseudo-Selektoren haben kein Leerzeichen nach dem &. Oder anders herum: Nur bei Element-Selektoren sitzt ein trennendes Leerzeichen zwischen dem & und dem Selektor.

header h2 { color:tomato; }
header h2.entry-title { color: green; }

Sitzt also Leerzeichen zwischen & und dem Selektor, liegt ein class-Selektor für dieses Element vor, mit einem Leerzeichen wird ein untergeordnetes Element referenziert. Das gilt auch für id-Selektoren, : und ::, für * und die Spielarten +, ~, > und für [] (Attribut-Selektoren).

Aus dem klassischen CSS oberhalb wird zu

header {
	& h2 { // mit Leerzeichen
		color: tomato;
		&.entry-title { // kein Leerzeichen
			color: green;
		}
	}
}

Ersetzt man jetzt jedes & mit dem Selektor des übergeordneten Elements entsteht, wieder das ursprüngliche – nicht verschachtelte – CSS.

header h2 {color: tomato; }
header h2.entry-title {color: green;}

Kompaktes CSS

Je kürzer die CSS-Regeln gehalten werden, desto lesbarer wird die CSS-Datei. Was in der linearen Schreibweise noch viele Zeilen einnimmt, läßt sich deutlich reduzieren.

 
#blog-layout h2, 
#blog-layout ul, 
#blog-layout div,
#blog-layout p {
	padding: 0 1rem;
	max-width: 320px;
	margin: 0 auto;
	color: darkblue;
} 

Mein kleiner Blog

Hallo Absatz!

  • Punkt 1
  • Punkt 2

In einem ersten Schritt fasst der :is-Selektor die beteiligten Selektoren zusammen:

:is(#blog-layout) p, ul, h2, div {
	padding: 0 1rem;
	max-width: 320px;
	margin: 0 auto;
	color: darkblue;
}

Auf dieselbe Weise übernimmt das Nesting die Regeln.

#blog-layout {
	& h2, & ul, & div, & p {
		padding: 0 1rem;
		max-width: 320px;
		margin: 0 auto;
		color: darkblue;
	}
}

CSS Nesting und Spezifität

Die Spezifität ist ein Regelsatz, der bestimmt, welche Regeln auf ein Element angewendet werden, wenn zwei oder mehr Selektoren für dasselbe Element notiert sind. In der CSS-Kaskade hat unter normalen Umständen der letzte Selektor das höchste Gewicht.

<article id="excerpt">
	<div>
		<h2 class="main-heading">Überschrift auf Ebene 2</h2>
	</div>
</article>

<article class="normal">
	<div>
		<h3>Überschrift auf Ebene 3</h3>
	</div>
</article>

Überschrift auf Ebene 2

Überschrift auf Ebene 3

Der Block ist mit den folgenden Stilen gestylt:

#excerpt, .normal {
	background: seashell;
	margin: 0.5rem;
	padding: 1rem;
	& h2, & h3 {
		color: tomato
	}
}

Wenn die Klasse main-heading des h2-Elements an einer später folgenden Stelle verwendet wird, passiert … nichts (!).

.main-heading {
	color: blue;
}

Die zusätzliche Regel an einer späteren Position überschreibt die Farbe für das h2-Element nicht. Die verschachtelten Regeln lassen sich ja auch mit einem :is()-Selektor schreiben:

:is(#excerpt, .normal) h1, h2 {
	color: tomato
}

Ein :is()-Selektor übernimmt die Spezifität des Elements der höchsten Spezifität. Im vorangegangenen Beispiel ist das der id-Selektor #excerpt. Die Stile des id-Selektors haben eine sehr hohe Priorität, so das es schwer ist, diese Stile zu überschreiben.

Dieses Verhalten vermeidet, dass immer komplexere Selektoren oder !important benötigt werden, um Elemente von weiteren Stilen abzuschotten.

Kann CSS-Nesting heute schon genutzt werden?

Die volle Unterstützung bei dem Mainstream-Browsern hat Nesting zwar erst seit Ende 2024, aber schon Mitte 24 unterstützten die Browser Nesting, wenn Element-Selektoren mit einem führenden & geschrieben wurden.

Wem das zu knapp erscheint, aber es trotzdem versuchen möchte, kann Javascript einsetzen. supportsCSSNesting enthält die Abfrage, ob Nesting vom aktuellen Browser unterstützt wird. Wenn nicht, ersetzt das Skript kurzerhand die CSS-Datei mit der älteren Version.

function supportsCSSNesting() {
	try {
		document.querySelector("&");
		return true;
	} catch (e) {
		const link = document.querySelector ("link[href='/css/nesting.css']");
		link.href = "/style/style.css";
		return false;
	}
}
supportsCSSNesting();