Eine unserer bevorzugten CSS-Präprozessorfunktionen ist jetzt in die Sprache integriert: die Stilregeln für Verschachtelungen.
Vor der Verschachtelung musste jeder Selektor explizit und separat deklariert werden. Dies führt zu Wiederholungen, zu umfangreichen Stylesheets und zu einer unübersichtlichen Entwicklung.
.nesting { color: hotpink; } .nesting > .is { color: rebeccapurple; } .nesting > .is > .awesome { color: deeppink; }
Nach der Verschachtelung können Selektoren fortgesetzt und zugehörige Stilregeln können gruppiert werden.
.nesting { color: hotpink; > .is { color: rebeccapurple; > .awesome { color: deeppink; } } }
Verschachtelungen helfen Entwicklern, da Selektoren nicht wiederholt werden müssen. Gleichzeitig werden Stilregeln für verwandte Elemente an einem Ort gespeichert. Außerdem können die Stile dem HTML-Code entsprechen, auf den sie ausgerichtet sind. Wenn die Komponente .nesting
im vorherigen Beispiel aus dem Projekt entfernt wurde, können Sie die gesamte Gruppe löschen, anstatt Dateien nach zugehörigen Selektorinstanzen zu durchsuchen.
Verschachtelung kann bei Folgendem helfen: – Organisation – Verringern der Dateigröße – Refaktorierung
Die Verschachtelung ist ab Chrome 112 verfügbar und kann auch in der technischen Vorschau von Safari 162 getestet werden.
Erste Schritte mit der Verschachtelung von Preisvergleichsportalen
Im weiteren Verlauf dieses Beitrags wird dir die folgende Demo-Sandbox verwendet,um dir die Auswahl zu visualisieren. In diesem Standardstatus ist nichts ausgewählt und alles ist sichtbar. Durch Auswahl der Formen und Größen können Sie die Syntax üben und sie in Aktion erleben.
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 innerhalb des .demo
-Elements. Im Folgenden sehen Sie eine Vorschau der HTML-Elemente, auf die Sie Ihre Anzeigen ausrichten.
<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 Verschachtelungen
Mithilfe von CSS-Verschachtelungen 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 Klassenselektor .child
im Klassenselektor .parent
verschachtelt. Das bedeutet, dass der verschachtelte .child
-Selektor nur auf Elemente angewendet wird, die untergeordnete Elemente von Elementen mit einer .parent
-Klasse sind.
Dieses Beispiel könnte 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 äquivalent. Die Gründe, warum Ihnen Optionen zur Verfügung stehen, werden deutlicher, wenn in diesem Artikel fortgeschrittenere Beispiele behandelt werden.
Kreise auswählen
In diesem ersten Beispiel besteht die Aufgabe darin, Stile hinzuzufügen, mit denen nur die Kreise in der Demo ausgeblendet und unkenntlich gemacht werden.
Ohne Verschachtelung gilt für CSS derzeit Folgendes:
.demo .circle {
opacity: .25;
filter: blur(25px);
}
Bei Verschachtelungen gibt es zwei 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 innerhalb von .demo
mit der Klasse .circle
sind unkenntlich gemacht und nahezu unsichtbar:
Dreiecke und Quadrate auswählen
Dazu müssen mehrere verschachtelte Elemente ausgewählt werden. Dies wird auch als Gruppenauswahl bezeichnet.
Ohne Verschachtelung gibt es bei CSS derzeit 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);
}
Bei Verschachtelung gibt es zwei Möglichkeiten:
.demo {
& .triangle,
& .square {
opacity: .25;
filter: blur(25px);
}
}
oder
.demo {
.triangle, .square {
opacity: .25;
filter: blur(25px);
}
}
Das Ergebnis. Nur .circle
-Elemente verbleiben innerhalb von .demo
:
Große Dreiecke und Kreise auswählen
Für diese Aufgabe ist ein zusammengesetzter Selektor erforderlich, bei dem für Elemente beide Klassen vorhanden sein müssen, damit sie ausgewählt werden können.
Ohne Verschachtelung gilt für CSS derzeit Folgendes:
.demo .lg.triangle,
.demo .lg.square {
opacity: .25;
filter: blur(25px);
}
oder
.demo .lg:is(.triangle, .circle) {
opacity: .25;
filter: blur(25px);
}
Bei Verschachtelung gibt es zwei 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:
Profitipp mit zusammengesetzten Selektoren und Verschachtelung
Das Symbol &
eignet sich besonders gut, da es explizit zeigt, wie verschachtelte Selektoren angehängt werden. Dazu ein Beispiel:
.demo {
.lg {
.triangle,
.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Die Verschachtelung ist zwar sinnvoll, aber die Ergebnisse stimmen nicht mit den Elementen überein, die Sie erwarten.
Der Grund dafür ist, dass ohne &
das gewünschte Ergebnis der Kombination von .lg.triangle,
.lg.circle
das tatsächliche Ergebnis .lg .triangle, .lg
.circle
; Nachfolgeselektoren wäre.
Alle Formen außer den rosafarbenen auswählen
Für diese Aufgabe ist eine Pseudoklasse für die Negationsfunktion erforderlich, bei der Elemente nicht den angegebenen Selektor haben dürfen.
Ohne Verschachtelung gilt für CSS derzeit Folgendes:
.demo :not(.pink) {
opacity: .25;
filter: blur(25px);
}
Bei Verschachtelung gibt es zwei 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 ein Targeting auf .demo
mit dem Selektor :not()
vornehmen. Hierfür ist &
erforderlich:
.demo {
&:not() {
...
}
}
Dabei werden .demo
und :not()
mit .demo:not()
verknüpft, im Gegensatz zum vorherigen Beispiel, in dem .demo :not()
erforderlich war. Diese Erinnerung ist besonders wichtig, wenn Sie eine :hover
-Interaktion verschachteln möchten.
.demo {
&:hover {
/* .demo:hover */
}
:hover {
/* .demo :hover */
}
}
Weitere Beispiele für Verschachtelungen
Die CSS-Spezifikation zum Verschachteln enthält viele weitere Beispiele. Wenn Sie anhand von Beispielen mehr über die Syntax erfahren möchten, finden Sie hier eine Vielzahl gültiger und ungültiger Beispiele.
In den nächsten Beispielen wird kurz eine CSS-Verschachtelungsfunktion vorgestellt, damit Sie die Bandbreite der damit verbundenen Funktionen besser verstehen.
@media verschachteln
Es kann sehr ablenken, zu einem anderen Bereich des Stylesheets zu wechseln, um Bedingungen für Medienabfragen zu finden, die einen Selektor und seine Stile ändern. Diese Ablenkung geht durch die Möglichkeit, die Bedingungen direkt im Kontext zu verschachteln.
Wenn die verschachtelte Medienabfrage nur die Stile für den aktuellen Selektorkontext ändert, kann zur Vereinfachung der Syntax eine minimale Syntax verwendet werden.
.card {
font-size: 1rem;
@media (width >= 1024px) {
font-size: 1.25rem;
}
}
Die explizite Verwendung von &
kann auch verwendet werden:
.card {
font-size: 1rem;
@media (width >= 1024px) {
&.large {
font-size: 1.25rem;
}
}
}
Dieses Beispiel zeigt die erweiterte Syntax mit &
. Es wird aber auch auf .large
-Karten ausgerichtet, um zu zeigen, dass zusätzliche Verschachtelungsfeatures weiterhin funktionieren.
Weitere Informationen zum Verschachteln von @rules
Überall verschachtelt
Alle Beispiele bis zu diesem Punkt wurden fortgesetzt oder an einen vorherigen Kontext angehängt. Bei Bedarf können Sie den Kontext komplett ändern oder neu anordnen.
.card {
.featured & {
/* .featured .card */
}
}
Das Symbol &
steht für einen Verweis auf ein Selektorobjekt (kein String) und kann an einer beliebigen Stelle in einem verschachtelten Selektor platziert werden. Sie 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.
Beispiele für ungültige Verschachtelungen
Es gibt einige Szenarien für die Verschachtelungssyntax, die ungültig sind und Sie möglicherweise überraschen, wenn Sie in Präprozessoren verschachtelt haben.
Verschachtelung und Verkettung
Bei vielen Namenskonventionen für CSS-Klassen kann die Verschachtelung von Selektoren so verkettet oder angehängt werden, als wären es Strings. Dies funktioniert bei CSS-Verschachtelungen nicht, da die Selektoren keine Strings, sondern Objektverweise sind.
.card {
&--header {
/* is not equal to ".card--header" */
}
}
Eine ausführlichere Erläuterung finden Sie in der Spezifikation.
Beispiel für komplizierte Verschachtelung
Verschachtelung in Auswahllisten und :is()
Betrachten Sie den folgenden verschachtelten CSS-Block:
.one, #two {
.three {
/* some styles */
}
}
Dies ist das erste Beispiel, das mit einer Selektorliste beginnt und dann weiter verschachtelt wird. Vorherige Beispiele wurden nur mit einer Auswahlliste beendet. In diesem Verschachtelungsbeispiel gibt es nichts ungültiges, aber es gibt ein möglicherweise kompliziertes Implementierungsdetail bei der Verschachtelung in Selektorlisten, insbesondere in solchen, die einen ID-Selektor enthalten.
Damit die Verschachtelung funktioniert, wird jede Selektorliste, die nicht die innerste Verschachtelung ist, vom Browser mit :is()
umschlossen. Durch dieses Wrapping wird die Gruppierung der Selektorliste innerhalb aller erstellten Kontexte beibehalten. Der Nebeneffekt dieser Gruppierung, :is(.one, #two)
, besteht darin, dass sie die Spezifität des höchsten Werts innerhalb der Selektoren innerhalb der Klammern übernimmt. So funktioniert :is()
immer, es könnte jedoch überrascht sein, wenn Sie die Verschachtelungssyntax verwenden, da diese nicht genau dem entspricht, was erstellt wurde. Der Trick zusammengefasst: Das Verschachteln mit IDs und Selektorlisten kann zu Selektoren mit sehr hoher Spezifität führen.
Um das schwierige Beispiel kurz zusammenzufassen, wird der vorherige Verschachtelungsblock so auf das Dokument angewendet:
:is(.one, #two) .three {
/* some styles */
}
Achten Sie auf die Verschachtelung oder bringen Sie Ihren Linters bei, gewarnt zu werden, wenn sie in einer Selektorliste verschachteln, die einen ID-Selektor verwendet, ist die Spezifität aller Verschachtelungen innerhalb dieser Selektorliste hoch.
Verschachtelung und Deklarationen kombinieren
Betrachten Sie den folgenden verschachtelten CSS-Block:
.card {
color: green;
& { color: blue; }
color: red;
}
Die Farbe von .card
-Elementen ist blue
.
Alle vermischten Stildeklarationen werden nach oben gezogen, als wären sie vor einer Verschachtelung erstellt worden. Weitere Informationen finden Sie in der Spezifikation.
Es gibt verschiedene Möglichkeiten, sie zu umgehen. Im folgenden Beispiel werden die drei Farbstile in &
umschlossen, wodurch die Kaskadenreihenfolge wie vom Autor beabsichtigt beibehalten wird. Die Farbe von .card
-Elementen ist Rot.
.card {
color: green;
& { color: blue; }
& { color: red; }
}
Es hat sich sogar bewährt, alle Stile, die einer Verschachtelung folgen, mit einem &
zu versehen.
.card {
color: green;
@media (prefers-color-scheme: dark) {
color: lightgreen;
}
& {
aspect-ratio: 4/3;
}
}
Funktionserkennung
Es gibt zwei großartige Möglichkeiten, CSS-Verschachtelungen mithilfe von Features zu erkennen: Verwenden Sie die Verschachtelung oder verwenden Sie @supports
, um die Parsing-Funktion von Verschachtelungsselektoren zu prüfen.
Verschachtelung verwenden:
html {
.has-nesting {
display: block;
}
.no-nesting {
display: none;
}
}
mit @supports
:
@supports (selector(&)) {
/* nesting parsing available */
}
Mein Kollege Bramus hat einen tollen Codepen, der diese Strategie verdeutlicht.
Fehlerbehebung mit den Chrome-Entwicklertools
Derzeit wird das Verschachteln in den Entwicklertools nur minimal unterstützt. Derzeit werden Stile wie erwartet im Bereich „Stile“ dargestellt. Das Nachzeichnen der Verschachtelung und des vollständigen Selektorkontexts wird jedoch noch nicht unterstützt. Wir haben Design und Pläne, um dies transparent und klar zu machen.
Für Chrome 113 ist eine zusätzliche Unterstützung für CSS-Verschachtelungen geplant. Bleib also dran!
Die Zukunft
CSS-Verschachtelung ist nur ab Version 1 verfügbar. Version 2 wird mehr syntaktischen Zucker und möglicherweise weniger Regeln einführen, die Sie sich merken müssen. Das Parsen von Verschachtelungen ist gefragt, um nicht begrenzt zu sein oder schwierige Momente zu haben.
Verschachtelung ist eine große Verbesserung der CSS-Sprache. Es wirkt sich auf fast jeden architektonischen Aspekt von CSS aus. Diese großen Auswirkungen müssen gründlich erforscht und verstanden werden, bevor Version 2 effektiv spezifiziert werden kann.
Zum Abschluss finden Sie hier eine Demo, in der @scope
, Verschachtelung und @layer
verwendet werden. Das ist total aufregend!