Eine unserer beliebtesten CSS-Präprozessorfunktionen ist jetzt in die Sprache integriert: verschachtelte Stilregeln.
Vor der Verschachtelung musste jeder Selektor explizit und getrennt voneinander deklariert werden. Dies führt zu Wiederholungen, zu großen Stylesheets und zu unterschiedlichen Erstellungserfahrungen.
.nesting { color: hotpink; } .nesting > .is { color: rebeccapurple; } .nesting > .is > .awesome { color: deeppink; }
Nach der Verschachtelung können Selektoren fortgesetzt und zugehörige Stilregeln gruppiert werden.
.nesting { color: hotpink; > .is { color: rebeccapurple; > .awesome { color: deeppink; } } }
Die Verschachtelung hilft Entwicklern, da Selektoren nicht wiederholt werden müssen, während Stilregeln für verwandte Elemente gemeinsam gespeichert werden. Außerdem lassen sich Stile so
an das HTML anpassen, auf das sie ausgerichtet sind. Wenn die Komponente .nesting
im vorherigen Beispiel aus dem Projekt entfernt wurde, können Sie die gesamte Gruppe löschen, anstatt in Dateien nach verwandten Selektorinstanzen zu suchen.
Die Verschachtelung kann bei Folgendem helfen: – Organisation – Reduzierung der Dateigröße – Refaktorierung
Nesting ist ab Chrome 112 verfügbar und kann auch in Safari Technical Preview 162 getestet werden.
Erste Schritte mit der CSS-Verschachtelung
Im weiteren Verlauf dieses Posts wird die folgende Demo-Sandbox verwendet,um die Auswahl zu visualisieren. In diesem Standardstatus 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.
Innerhalb 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 Elements .demo
, das das Element enthält. Im Folgenden sehen Sie eine Vorschau der HTML-Elemente, auf die Sie das Targeting vornehmen werden.
<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
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 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;
}
}
Die Funktionen dieser beiden Beispiele sind äquivalent. In diesem Artikel werden fortgeschrittenere Beispiele erläutert, und die Gründe für Ihre Optionen werden deutlicher.
Kreise auswählen
In diesem ersten Beispiel besteht die Aufgabe darin, Stile zum Ausblenden und Unkenntlichmachen der Kreise in der Demo hinzuzufügen.
Ohne Verschachtelung bietet CSS jetzt Folgendes:
.demo .circle {
opacity: .25;
filter: blur(25px);
}
Bei Verschachtelungen 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);
}
}
Im Ergebnis werden alle Elemente in .demo
mit einer .circle
-Klasse unkenntlich gemacht und sind fast unsichtbar:
Dreiecke und Quadrate auswählen
Für diese Aufgabe müssen mehrere verschachtelte Elemente ausgewählt werden, die auch als Gruppenselektor bezeichnet werden.
Ohne Verschachtelung gibt es bei CSS jetzt zwei Möglichkeiten:
.demo .triangle,
.demo .square {
opacity: .25;
filter: blur(25px);
}
oder :is()
verwenden
/* grouped with :is() */
.demo :is(.triangle, .square) {
opacity: .25;
filter: blur(25px);
}
Bei der Verschachtelung gibt es zwei Möglichkeiten:
.demo {
& .triangle,
& .square {
opacity: .25;
filter: blur(25px);
}
}
oder
.demo {
.triangle, .square {
opacity: .25;
filter: blur(25px);
}
}
Als Ergebnis verbleiben nur .circle
-Elemente innerhalb von .demo
:
Große Dreiecke und Kreise auswählen
Für diese Aufgabe ist ein zusammengesetzter Selektor erforderlich, bei dem Elemente beide Klassen haben müssen, um ausgewählt zu werden.
Ohne Verschachtelung bietet CSS jetzt Folgendes:
.demo .lg.triangle,
.demo .lg.square {
opacity: .25;
filter: blur(25px);
}
oder
.demo .lg:is(.triangle, .circle) {
opacity: .25;
filter: blur(25px);
}
Bei der 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);
}
}
}
Als Ergebnis werden alle großen Dreiecke und Kreise innerhalb von .demo
ausgeblendet:
Profitipp mit Compound-Selektoren und Verschachtelung
Hier können Sie das &
-Symbol verwenden, da es explizit zeigt, wie verschachtelte Selektoren verbunden werden. Dazu ein Beispiel:
.demo {
.lg {
.triangle,
.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Das ist zwar eine zulässige Verschachtelungsmethode, aber die Ergebnisse stimmen nicht mit den Elementen überein, die Sie möglicherweise erwarten.
Der Grund dafür ist, dass ohne &
das gewünschte Ergebnis der kombinierten .lg.triangle,
.lg.circle
-Funktion angegeben wird, wäre das tatsächliche Ergebnis .lg .triangle, .lg
.circle
; Nachgeordnete Selektoren.
Alle Formen außer den rosafarbenen Formen werden ausgewählt
Diese Aufgabe erfordert eine funktionale Pseudoklasse für die Negation, in der Elemente nicht den angegebenen Selektor haben dürfen.
Ohne Verschachtelung bietet CSS jetzt Folgendes:
.demo :not(.pink) {
opacity: .25;
filter: blur(25px);
}
Bei der Verschachtelung gibt es zwei Möglichkeiten:
.demo {
:not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
oder
.demo {
& :not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
Als Ergebnis werden alle Formen, die nicht rosa sind, innerhalb von .demo
ausgeblendet:
Präzision und Flexibilität mit &
Angenommen, Sie möchten ein Targeting auf .demo
mit der :not()
-Auswahl vornehmen. &
ist hierfür erforderlich:
.demo {
&:not() {
...
}
}
Dadurch werden .demo
und :not()
zu .demo:not()
verbunden, im Gegensatz zum vorherigen Beispiel, für das .demo :not()
erforderlich war. Diese Erinnerung ist sehr wichtig, wenn eine :hover
-Interaktion verschachtelt werden soll.
.demo {
&:hover {
/* .demo:hover */
}
:hover {
/* .demo :hover */
}
}
Weitere Beispiele für Verschachtelungen
Die CSS-Spezifikation für Verschachtelungen enthält 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 du die Bandbreite der damit eingebauten Funktionen besser verstehen kannst.
@media verschachteln
Es kann sehr ablenkend sein, zu einem anderen Bereich des Stylesheets zu wechseln, um Bedingungen für Medienabfragen zu finden, die einen Selektor und seine Stile ändern. Diese Ablenkung wird durch die Möglichkeit beseitigt, die Bedingungen direkt in den Kontext zu verschachteln.
Zur Vereinfachung der Syntax kann eine minimale Syntax verwendet werden, wenn die verschachtelte Medienabfrage nur die Stile für den aktuellen Selektorkontext ändert.
.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 &
und ein Targeting auf .large
-Karten, um zusätzliche Verschachtelungsfunktionen zu demonstrieren.
Weitere Informationen zum Verschachteln von @rules
Überall verschachteln
Alle Beispiele bis jetzt wurden einem vorherigen Kontext hinzugefügt oder beibehalten. Sie können den Kontext bei Bedarf komplett ändern oder neu anordnen.
.card {
.featured & {
/* .featured .card */
}
}
Das &
-Symbol steht für einen Verweis auf ein Selector-Objekt (kein String) und kann an einer beliebigen Stelle in einem verschachtelten Selektor platziert werden. Er kann sogar mehrmals platziert werden:
.card {
.featured & & & {
/* .featured .card .card .card */
}
}
Obwohl dieses Beispiel etwas nutzlos aussieht, gibt es sicherlich Szenarien, in denen die Wiederholung eines Selektorkontexts praktisch ist.
Ungültige Verschachtelungsbeispiele
Es gibt einige Szenarien für Verschachtelungssyntax, die ungültig sind und Sie möglicherweise überraschen, wenn Sie in Präprozessoren verschachtelt haben.
Verschachtelung und Verkettung
Viele CSS-Klassen-Namenskonventionen setzen voraus, dass bei der Verschachtelung Selektoren wie Strings verkettet oder angehängt werden können. Dies funktioniert nicht bei der CSS-Verschachtelung, 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 eine komplizierte Verschachtelung
Verschachtelung in Selektorlisten 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 endeten nur mit einer Auswahlliste. In diesem Verschachtelungsbeispiel ist nichts ungültig, aber die Implementierung von Verschachtelungen innerhalb von Selectorlisten kann kompliziert sein. Dies gilt insbesondere für Listen, die einen ID-Selektor enthalten.
Damit die Verschachtelung funktioniert, wird jede Auswahlliste, die nicht die innerste Verschachtelung ist, vom Browser in :is()
zusammengefasst. 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 Klammer übernimmt. So funktioniert :is()
immer, kann jedoch bei Verwendung der Verschachtelungssyntax überrascht sein, da sie nicht genau dem entspricht, was erstellt wurde. Der Trick zusammengefasst: Das Verschachteln mit IDs und Selektorlisten kann zu sehr hohen Spezifitäts-Selektoren führen.
Um das knifflige Beispiel noch einmal zusammenzufassen, wird der vorherige Verschachtelungsblock wie folgt auf das Dokument angewendet:
:is(.one, #two) .three {
/* some styles */
}
Achten Sie auf die Linter oder bringen Sie ihnen bei, sie zu warnen, wenn sie in einer Selektorliste verschachtelt sind, die einen ID-Selektor verwendet. In diesem Fall sind alle Verschachtelungen innerhalb dieser Selektorliste sehr spezifisch.
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, so als ob sie vor einer Verschachtelung erstellt worden wären. Weitere Informationen finden Sie in der Spezifikation.
Es gibt Wege, das zu umgehen. Im Folgenden sind die drei Farbstile in &
zusammengefasst, wodurch die Kaskadenreihenfolge beibehalten wird, wie vom Autor beabsichtigt. Die Farbe von .card
-Elementen ist rot.
.card {
color: green;
& { color: blue; }
& { color: red; }
}
Tatsächlich empfiehlt es sich, alle Stile, die der Verschachtelung folgen, mit einem &
zu umschließen.
.card {
color: green;
@media (prefers-color-scheme: dark) {
color: lightgreen;
}
& {
aspect-ratio: 4/3;
}
}
Funktionserkennung
Es gibt zwei Möglichkeiten, eine CSS-Verschachtelung anhand von Features zu erkennen: Verwenden Sie eine Verschachtelung oder @supports
, um zu prüfen, ob der Verschachtelungsselektor geparst werden kann.
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 zeigt.
Fehlerbehebung mit den Chrome-Entwicklertools
Die Verschachtelung wird in den Entwicklertools aktuell nur minimal unterstützt. Derzeit werden Stile wie erwartet im Bereich „Styles“ dargestellt, das Tracing der Verschachtelung und ihres vollständigen Selektorkontexts wird jedoch noch nicht unterstützt. Wir haben Design und Pläne, dies transparent und klar zu gestalten.
Für Chrome 113 ist weitere Unterstützung für die CSS-Verschachtelung geplant. Bitte haben Sie noch etwas Geduld.
Die Zukunft
Die Verschachtelung von Preisvergleichsportalen ist erst ab Version 1 verfügbar. In Version 2 gibt es mehr syntaktischen Zucker und möglicherweise weniger Regeln, die Sie sich merken müssen. Das Parsen von Verschachtelungen wird stark nachgefragt, um nicht eingeschränkt zu sein oder knifflige Momente zu haben.
Verschachtelung ist eine große Verbesserung der CSS-Sprache. Bei fast jedem architektonischen Aspekt von CSS sind die Auswirkungen auf die Entwicklung zu berücksichtigen. Diese großen Auswirkungen müssen eingehend untersucht und verstanden werden, bevor Version 2 effektiv spezifiziert werden kann.
Zum Schluss finden Sie hier eine Demo, in der @scope
, Verschachtelung und @layer
verwendet werden. Das ist alles sehr aufregend!