Eine unserer Lieblingsfunktionen von CSS-Präprozessoren ist jetzt in die Sprache integriert: das Verschachteln von Stilregeln.
Vor der Verschachtelung musste jeder Selektor explizit und separat deklariert werden. Das führte zu Wiederholungen, großen Stylesheets und einer unübersichtlichen Autorenumgebung.
.nesting { color: hotpink; } .nesting > .is { color: rebeccapurple; } .nesting > .is > .awesome { color: deeppink; }
Nach der Verschachtelung können Selektoren fortgesetzt und zugehörige Stilregeln darin gruppiert werden.
.nesting { color: hotpink; > .is { color: rebeccapurple; > .awesome { color: deeppink; } } }
Die Verschachtelung hilft Entwicklern, da sie die Notwendigkeit reduziert, Selektoren zu wiederholen, und gleichzeitig Stilregeln für verwandte Elemente zusammenfasst. Außerdem können Stile so besser mit dem HTML-Code übereinstimmen, auf den sie angewendet werden. Wenn die Komponente .nesting im vorherigen Beispiel aus dem Projekt entfernt wurde, können Sie die gesamte Gruppe löschen, anstatt in Dateien nach zugehörigen Selektorinstanzen zu suchen.
Die Verschachtelung kann in folgenden Bereichen helfen: - Organisation - Reduzierung der Dateigröße - Refactoring
Die Verschachtelung ist ab Chrome 112 und auch in der Safari Technical Preview 162 verfügbar.
Erste Schritte mit der CSS-Verschachtelung
Im restlichen Teil dieses Beitrags wird die folgende Demo-Sandbox verwendet,um die Auswahl zu visualisieren. In diesem Standardzustand ist nichts ausgewählt und alles ist sichtbar. Wenn Sie die verschiedenen Formen und Größen auswählen, können Sie die Syntax üben und in Aktion sehen.

In der Sandbox befinden sich Kreise, Dreiecke und Quadrate. Einige sind klein, mittel oder groß. Andere sind blau, rosa oder lila. Sie befinden sich alle im Containerelement .demo. Im Folgenden sehen Sie eine Vorschau der HTML-Elemente, auf die Sie abzielen.
<div class="demo">
<div class="sm triangle pink"></div>
<div class="sm triangle blue"></div>
<div class="square blue"></div>
<div class="sm square pink"></div>
<div class="sm square blue"></div>
<div class="circle pink"></div>
…
</div>
Beispiele für die Verschachtelung
Mit der CSS-Verschachtelung können Sie Stile für ein Element im Kontext eines anderen Selektors definieren.
.parent {
color: blue;
.child {
color: red;
}
}
In diesem Beispiel ist der .child Klassenselektor in
den .parent Klassenselektor verschachtelt. Das bedeutet, dass der verschachtelte Selektor .child nur auf Elemente angewendet wird, die untergeordnete Elemente von Elementen mit der Klasse .parent sind.
Dieses Beispiel kann alternativ mit dem Symbol & geschrieben werden, um explizit anzugeben, wo die übergeordnete Klasse platziert werden soll.
.parent {
color: blue;
& .child {
color: red;
}
}
Diese beiden Beispiele sind funktional gleichwertig. Der Grund für die verschiedenen Optionen wird deutlicher, wenn wir uns komplexere Beispiele ansehen.
Kreise auswählen
In diesem ersten Beispiel sollen nur die Kreise in der Demo ausgeblendet und unscharf gemacht werden.
Ohne Verschachtelung, CSS heute:
.demo .circle {
opacity: .25;
filter: blur(25px);
}
Mit Verschachtelung gibt es zwei gültige Möglichkeiten:
/* & is explicitly placed in front of .circle */
.demo {
& .circle {
opacity: .25;
filter: blur(25px);
}
}
oder
/* & + " " space is added for you */
.demo {
.circle {
opacity: .25;
filter: blur(25px);
}
}
Das Ergebnis: Alle Elemente in .demo mit der Klasse .circle sind
unscharf und fast unsichtbar:
Alle Dreiecke und Quadrate auswählen
Für diese Aufgabe müssen mehrere verschachtelte Elemente ausgewählt werden, auch Gruppenselektor genannt.
Ohne Verschachtelung, CSS heute, gibt es zwei Möglichkeiten:
.demo .triangle,
.demo .square {
opacity: .25;
filter: blur(25px);
}
oder mit :is():
/* grouped with :is() */
.demo :is(.triangle, .square) {
opacity: .25;
filter: blur(25px);
}
Mit Verschachtelung gibt es zwei gültige Möglichkeiten:
.demo {
& .triangle,
& .square {
opacity: .25;
filter: blur(25px);
}
}
oder
.demo {
.triangle, .square {
opacity: .25;
filter: blur(25px);
}
}
Das Ergebnis: Nur .circle Elemente bleiben in .demo übrig:
Große Dreiecke und Kreise auswählen
Für diese Aufgabe ist ein zusammengesetzter Selektor erforderlich, wobei Elemente beide Klassen haben müssen, um ausgewählt zu werden.
Ohne Verschachtelung, CSS heute:
.demo .lg.triangle,
.demo .lg.square {
opacity: .25;
filter: blur(25px);
}
oder
.demo .lg:is(.triangle, .circle) {
opacity: .25;
filter: blur(25px);
}
Mit Verschachtelung gibt es zwei gültige Möglichkeiten:
.demo {
.lg.triangle,
.lg.circle {
opacity: .25;
filter: blur(25px);
}
}
oder
.demo {
.lg {
&.triangle,
&.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Das Ergebnis: Alle großen Dreiecke und Kreise sind in .demo ausgeblendet:
Profi-Tipp für zusammengesetzte Selektoren und Verschachtelung
Das Symbol & ist hier hilfreich, da es explizit zeigt, wie verschachtelte Selektoren verknüpft werden. Dazu ein Beispiel:
.demo {
.lg {
.triangle,
.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Das ist zwar eine gültige Möglichkeit zur Verschachtelung, die Ergebnisse stimmen aber nicht mit den erwarteten Elementen überein.
Der Grund dafür ist, dass ohne & zur Angabe des gewünschten Ergebnisses von .lg.triangle,
.lg.circle zusammengesetzt, das tatsächliche Ergebnis .lg .triangle, .lg
.circle wäre, also Nachkommensselektoren.
Alle Formen außer den rosafarbenen auswählen
Für diese Aufgabe ist eine funktionale Pseudoklasse für die Negation erforderlich, bei der Elemente den angegebenen Selektor nicht haben dürfen.
Ohne Verschachtelung, CSS heute:
.demo :not(.pink) {
opacity: .25;
filter: blur(25px);
}
Mit Verschachtelung gibt es zwei gültige Möglichkeiten:
.demo {
:not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
oder
.demo {
& :not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
Das Ergebnis: Alle Formen, die nicht rosa sind, sind in .demo ausgeblendet:
Präzision und Flexibilität mit &
Angenommen, Sie möchten .demo mit dem Selektor :not() auswählen. Dazu ist & erforderlich:
.demo {
&:not() {
...
}
}
Dadurch werden .demo und :not() zu .demo:not() zusammengesetzt, im Gegensatz zum vorherigen
Beispiel, bei dem .demo :not() erforderlich war. Diese Erinnerung ist sehr wichtig, wenn Sie eine :hover-Interaktion verschachteln möchten.
.demo {
&:hover {
/* .demo:hover */
}
:hover {
/* .demo :hover */
}
}
Weitere Beispiele für die Verschachtelung
Die CSS-Spezifikation für die Verschachtelung enthält weitere Beispiele. Wenn Sie mehr über die Syntax anhand von Beispielen erfahren möchten, finden Sie dort eine breite Palette gültiger und ungültiger Beispiele.
In den nächsten Beispielen wird kurz eine Funktion für die CSS-Verschachtelung vorgestellt, damit Sie die Bandbreite der Möglichkeiten besser verstehen.
@media verschachteln
Es kann sehr ablenkend sein, zu einem anderen Bereich des Stylesheets zu wechseln, um Media-Query-Bedingungen zu finden, die einen Selektor und seine Stile ändern. Diese Ablenkung entfällt, da Sie die Bedingungen direkt im Kontext verschachteln können.
Aus Gründen der Syntax kann eine minimale Syntax verwendet werden, wenn die verschachtelte Media-Query nur die Stile für den aktuellen Selektorkontext ändert.
.card {
font-size: 1rem;
@media (width >= 1024px) {
font-size: 1.25rem;
}
}
Sie können auch explizit & verwenden:
.card {
font-size: 1rem;
@media (width >= 1024px) {
&.large {
font-size: 1.25rem;
}
}
}
In diesem Beispiel wird die erweiterte Syntax mit & verwendet und gleichzeitig auf .large-Karten ausgerichtet, um zu zeigen, dass zusätzliche Verschachtelungsfunktionen weiterhin funktionieren.
Weitere Informationen zum Verschachteln von @-Regeln
Verschachtelung überall
In allen bisherigen Beispielen wurde ein vorheriger Kontext fortgesetzt oder erweitert. Sie können den Kontext bei Bedarf vollständig ändern oder neu anordnen.
.card {
.featured & {
/* .featured .card */
}
}
Das Symbol & steht für einen Verweis auf ein Selektorobjekt (keine String) und kann an einer beliebigen Stelle in einem verschachtelten Selektor platziert werden. Es kann sogar mehrmals platziert werden:
.card {
.featured & & & {
/* .featured .card .card .card */
}
}
Dieses Beispiel sieht zwar etwas nutzlos aus, aber es gibt sicherlich Szenarien, in denen es praktisch ist, einen Selektorkontext zu wiederholen.
Ungültige Beispiele für die Verschachtelung
Es gibt einige Szenarien für die Syntax der Verschachtelung, die ungültig sind und Sie möglicherweise überraschen, wenn Sie bereits in Präprozessoren verschachtelt haben.
Verschachtelung und Verkettung
Viele CSS-Klassennamenkonventionen gehen davon aus, dass Selektoren durch Verschachtelung verkettet oder angehängt werden können, als wären sie Strings. Das funktioniert bei der CSS-Verschachtelung nicht, da die Selektoren keine Strings, sondern Objektverweise sind.
.card {
&--header {
/* is not equal to ".card--header" */
}
}
Eine ausführlichere Erklärung finden Sie in der Spezifikation.
Kompliziertes Beispiel für die Verschachtelung
Verschachtelung in Selektorlisten und :is()
Sehen Sie sich den folgenden CSS-Block für die Verschachtelung an:
.one, #two {
.three {
/* some styles */
}
}
Dies ist das erste Beispiel, das mit einer Selektorliste beginnt und dann weiter verschachtelt wird. In den vorherigen Beispielen wurde nur mit einer Selektorliste geendet. Dieses Beispiel für die Verschachtelung ist nicht ungültig, es gibt aber ein potenziell kompliziertes Implementierungsdetail zur Verschachtelung in Selektorlisten, insbesondere in solchen, die einen ID-Selektor enthalten.
Damit die Verschachtelung wie beabsichtigt funktioniert, wird jede Selektorliste, die nicht die innerste Verschachtelung ist, vom Browser mit :is() umschlossen. Durch diese Umschließung bleibt die Gruppierung der Selektorliste in allen erstellten Kontexten erhalten. Der Nebeneffekt dieser Gruppierung, :is(.one, #two), ist, dass sie die Spezifität des höchsten Werts innerhalb der Selektoren in den Klammern übernimmt. Das ist die normale Funktionsweise von :is(), kann aber überraschend sein, wenn Sie die Syntax für die Verschachtelung verwenden, da sie nicht genau dem entspricht, was Sie geschrieben haben. Zusammenfassend lässt sich sagen, dass die Verschachtelung mit IDs und Selektorlisten zu Selektoren mit sehr hoher Spezifität führen kann.
Um das komplizierte Beispiel noch einmal zusammenzufassen: Der vorherige Verschachtelungsblock wird so auf das Dokument angewendet:
:is(.one, #two) .three {
/* some styles */
}
Achten Sie darauf oder weisen Sie Ihre Linter an, eine Warnung auszugeben, wenn Sie in einer Selektorliste verschachteln, die einen ID-Selektor verwendet. Die Spezifität aller Verschachtelungen in dieser Selektorliste ist dann hoch.
Verschachtelung und Deklarationen mischen
Sehen Sie sich den folgenden CSS-Block für die Verschachtelung an:
.card {
color: green;
& { color: blue; }
color: red;
}
Die Farbe der .card-Elemente ist blue.
Alle gemischten Stildeklarationen werden nach oben verschoben, als wären sie vor der Verschachtelung geschrieben worden. Weitere Informationen finden Sie in der Spezifikation.
Es gibt Möglichkeiten, das zu umgehen. Im Folgenden werden die drei Farbstile in & umschlossen, wodurch die Kaskadenreihenfolge beibehalten wird, wie vom Autor beabsichtigt. Die Farbe der .card-Elemente ist rot.
.card {
color: green;
& { color: blue; }
& { color: red; }
}
Es ist sogar eine gute Idee, alle Stile, die nach der Verschachtelung folgen, mit & zu umschließen.
.card {
color: green;
@media (prefers-color-scheme: dark) {
color: lightgreen;
}
& {
aspect-ratio: 4/3;
}
}
Funktionserkennung
Es gibt zwei gute Möglichkeiten, die CSS-Verschachtelung zu erkennen: Verwenden Sie die Verschachtelung selbst oder verwenden Sie @supports, um die Parsing-Funktion für verschachtelte Selektoren zu prüfen.

Verschachtelung verwenden:
html {
.has-nesting {
display: block;
}
.no-nesting {
display: none;
}
}
@supports verwenden:
@supports (selector(&)) {
/* nesting parsing available */
}
Mein Kollege Bramus hat ein tolles Codepen-Beispiel für diese Strategie.
Fehlerbehebung mit den Chrome-Entwicklertools
Die aktuelle Unterstützung für die Verschachtelung in den Entwicklertools ist minimal. Derzeit werden Stile wie erwartet im Bereich „Stile“ dargestellt, aber das Nachverfolgen der Verschachtelung und des vollständigen Selektorkontexts wird noch nicht unterstützt. Wir haben bereits ein Design und Pläne, um das zu ändern.

In Chrome 113 soll die Unterstützung für die CSS-Verschachtelung erweitert werden. Bleiben Sie dran!
Die Zukunft
Die CSS-Verschachtelung ist erst in Version 1 verfügbar. Version 2 wird mehr syntaktischen Zucker und möglicherweise weniger Regeln zum Merken enthalten. Es gibt eine große Nachfrage danach, dass das Parsing der Verschachtelung nicht eingeschränkt ist oder zu Problemen führt.
Die Verschachtelung ist eine große Verbesserung für die CSS-Sprache. Sie hat Auswirkungen auf fast alle architektonischen Aspekte von CSS. Diese großen Auswirkungen müssen gründlich untersucht und verstanden werden, bevor Version 2 effektiv spezifiziert werden kann.
Zum Schluss noch eine Demo, in der hier ist eine Demo
die @scope, Verschachtelung und @layer zusammen verwendet werden. Das ist wirklich spannend!
