Eine unserer Lieblingsfunktionen des CSS-Präprozessors ist jetzt in die Sprache integriert: verschachtelte Stilregeln.
Vor dem Verschachteln musste jeder Selektor explizit und getrennt voneinander deklariert werden. Dies führt zu Wiederholungen, einem großen Stylesheet-Volumen und einer unübersichtlichen Autorenansicht.
.nesting { color: hotpink; } .nesting > .is { color: rebeccapurple; } .nesting > .is > .awesome { color: deeppink; }
Nach dem Verschachteln können Selektoren fortgesetzt und zugehörige Stilregeln darin gruppiert werden.
.nesting { color: hotpink; > .is { color: rebeccapurple; > .awesome { color: deeppink; } } }
Durch das Verschachteln müssen Entwickler weniger Auswahlen wiederholen und können Stilregeln für zugehörige Elemente an einer Stelle platzieren. Außerdem können Stile so besser an das HTML angepasst werden, auf das sie ausgerichtet sind. Wenn die .nesting
-Komponente im vorherigen Beispiel aus dem Projekt entfernt wurde, können Sie die gesamte Gruppe löschen, anstatt in Dateien nach zugehörigen Auswahlinstanzen zu suchen.
Verschachtelung kann bei Folgendem helfen: - Organisation - Reduzierung der Dateigröße - Refactoring
Die Verschachtelung ist ab Chrome 112 verfügbar und kann auch in der Safari-Technischen Vorschau 162 getestet werden.
Erste Schritte mit CSS-Verschachtelung
Im restlichen Teil dieses Artikels wird die folgende Demo-Sandbox verwendet,um die Auswahlen zu veranschaulichen. 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.
In der Sandbox sind Kreise, Dreiecke und Quadrate zu sehen. Einige sind klein, mittel oder groß. Andere sind blau, rosa oder lila. Sie befinden sich alle im enthaltenden .demo
-Element. Unten sehen Sie eine Vorschau der HTML-Elemente, auf die Sie das Targeting vornehmen.
<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 Verschachtelung
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 .child
-Klassen-Selektor im .parent
-Klassen-Selektor verschachtelt. Das bedeutet, dass die verschachtelte .child
-Auswahl nur auf Elemente angewendet wird, die untergeordneten Elementen mit der Klasse .parent
sind.
Dieses Beispiel könnte alternativ mit dem Symbol &
geschrieben werden, um anzugeben, wo die übergeordnete Klasse platziert werden soll.
.parent {
color: blue;
& .child {
color: red;
}
}
Diese beiden Beispiele sind funktional gleichwertig. Der Grund, warum Sie Optionen haben, wird klarer, wenn in diesem Artikel fortgeschrittenere Beispiele erläutert werden.
Kreise auswählen
In diesem ersten Beispiel geht es darum, Stile hinzuzufügen, um nur die Kreise in der Demo auszublenden und zu verwischen.
Ohne Verschachtelung:
.demo .circle {
opacity: .25;
filter: blur(25px);
}
Bei 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);
}
}
Ergebnis: Alle Elemente in .demo
mit der Klasse .circle
sind unscharf und fast unsichtbar:
Dreiecke und Quadrate auswählen
Dazu müssen mehrere verschachtelte Elemente ausgewählt werden, auch als Gruppenauswahl bezeichnet.
Ohne Verschachtelung gibt es in CSS heute 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 gültige Möglichkeiten:
.demo {
& .triangle,
& .square {
opacity: .25;
filter: blur(25px);
}
}
oder
.demo {
.triangle, .square {
opacity: .25;
filter: blur(25px);
}
}
Ergebnis: Innerhalb von .demo
sind nur noch .circle
-Elemente vorhanden:
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:
.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 gültige Möglichkeiten:
.demo {
.lg.triangle,
.lg.circle {
opacity: .25;
filter: blur(25px);
}
}
oder
.demo {
.lg {
&.triangle,
&.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Ergebnis: Alle großen Dreiecke und Kreise sind in .demo
verborgen:
Profitipp zu zusammengesetzten Auswahlen und Verschachtelung
Das Symbol &
ist hier Ihr Freund, da es explizit zeigt, wie verschachtelte Auswahlen aneinandergefügt werden. Dazu ein Beispiel:
.demo {
.lg {
.triangle,
.circle {
opacity: .25;
filter: blur(25px);
}
}
}
Das ist zwar eine gültige Verschachtelung, die Ergebnisse stimmen jedoch nicht mit den erwarteten Elementen überein.
Das liegt daran, dass ohne &
, um das gewünschte Ergebnis der zusammengesetzten .lg.triangle,
.lg.circle
anzugeben, das tatsächliche Ergebnis .lg .triangle, .lg
.circle
wäre; Abkömmlingsauswahlen.
Alle Formen außer den rosafarbenen auswählen
Für diese Aufgabe ist eine funktionale Pseudoklasse für die Negation erforderlich, bei der Elemente nicht den angegebenen Selektor haben dürfen.
Ohne Verschachtelung:
.demo :not(.pink) {
opacity: .25;
filter: blur(25px);
}
Bei 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);
}
}
Ergebnis: Alle Formen, die nicht rosa sind, sind in .demo
ausgeblendet:
Präzision und Flexibilität mit &
Angenommen, Sie möchten die Auswahl :not()
auf .demo
ausrichten. &
ist erforderlich für Folgendes:
.demo {
&:not() {
...
}
}
Dadurch werden .demo
und :not()
zu .demo:not()
kombiniert, im Gegensatz zum vorherigen Beispiel, in 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 Verschachtelung
Die CSS-Spezifikation für das Verschachteln enthält weitere Beispiele. Wenn Sie mehr über die Syntax erfahren möchten, finden Sie dort eine Vielzahl gültiger und ungültiger Beispiele.
In den nächsten Beispielen wird kurz eine CSS-Verschachtelungsfunktion vorgestellt, damit Sie die Vielfalt der damit verbundenen Funktionen besser nachvollziehen können.
@media-Verschachtelung
Es kann sehr ablenkend sein, zu einem anderen Bereich des Stylesheets zu wechseln, um Bedingungen für Medienabfragen zu finden, die einen Auswählen und seine Stile ändern. Diese Ablenkung ist nicht mehr vorhanden, da die Bedingungen direkt im Kontext verschachtelt werden können.
Wenn die verschachtelte Medienabfrage nur die Stile für den aktuellen Auswahlkontext ändert, kann aus Gründen der Übersichtlichkeit eine minimale Syntax verwendet werden.
.card {
font-size: 1rem;
@media (width >= 1024px) {
font-size: 1.25rem;
}
}
Die explizite Verwendung von &
kann auch für Folgendes verwendet werden:
.card {
font-size: 1rem;
@media (width >= 1024px) {
&.large {
font-size: 1.25rem;
}
}
}
In diesem Beispiel wird die erweiterte Syntax mit &
gezeigt. Außerdem wird auf .large
-Karten ausgerichtet, um zu zeigen, dass zusätzliche Verschachtelungsfunktionen weiterhin funktionieren.
Weitere Informationen zum Verschachteln von @rules
Verschachteln an beliebiger Stelle
Alle bisherigen Beispiele haben einen vorherigen Kontext fortgesetzt oder an ihn angehängt. 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 Auswahlobjekt (kein String) und kann an einer beliebigen Stelle in einer verschachtelten Auswahl platziert werden. Sie kann sogar mehrmals platziert werden:
.card {
.featured & & & {
/* .featured .card .card .card */
}
}
Dieses Beispiel mag zwar etwas unnötig erscheinen, aber es gibt durchaus Szenarien, in denen es praktisch ist, einen Auswahlkontext wiederholen zu können.
Beispiele für ungültige Verschachtelung
Es gibt einige ungültige Syntaxszenarien für Verschachtelungen, die Sie vielleicht überraschen, wenn Sie in Preprocessorn verschachtelt haben.
Verschachtelung und Verkettung
Viele CSS-Namenskonventionen für Klassen setzen voraus, dass durch Verschachtelung Selektoren wie Strings zusammengefügt oder angehängt werden können. Dies funktioniert nicht bei CSS-Verschachtelungen, 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.
Beispiel für eine knifflige 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 Auswahlliste beginnt und dann weiter verschachtelt wird. Die vorherigen Beispiele endeten nur mit einer Auswahlliste. Dieses Verschachtelungsbeispiel ist nicht ungültig, aber es gibt ein potenziell heikles Implementierungsdetail beim Verschachteln in Auswahllisten, insbesondere in solchen, die eine ID-Auswahl enthalten.
Damit die Verschachtelung funktioniert, wird jede Auswahlliste, die nicht die innerste Verschachtelung ist, vom Browser in :is()
eingehüllt. Durch dieses Umbrechen wird die Gruppierung der Auswahlliste in allen erstellten Kontexten beibehalten. Die Nebenwirkung dieser Gruppierung, :is(.one, #two)
, besteht darin, dass die Spezifität der höchsten Punktzahl innerhalb der Selektoren in den Klammern übernommen wird. So funktioniert :is()
immer. Bei Verwendung der Verschachtelungssyntax kann das jedoch eine Überraschung sein, da es nicht genau dem entspricht, was erstellt wurde. Zusammenfassend lässt sich sagen, dass das Verschachteln mit IDs und Auswahllisten zu sehr spezifischen Auswahlkriterien führen kann.
Um das knifflige Beispiel noch einmal zusammenzufassen: Der vorherige Verschachtelungsblock wird auf das Dokument so angewendet:
:is(.one, #two) .three {
/* some styles */
}
Achten Sie darauf oder legen Sie fest, dass Ihre Linter warnen, wenn Sie eine Auswahlliste mit einer ID-Auswahl verschachteln. Die Spezifität aller Verschachtelungen in dieser Auswahlliste ist dann hoch.
Verschachtelung und Deklarationen kombinieren
Betrachten Sie den folgenden verschachtelten CSS-Block:
.card {
color: green;
& { color: blue; }
color: red;
}
Die Farbe der .card
-Elemente ist blue
.
Alle vermischten Stildeklarationen werden an den Anfang verschoben, als wären sie vor dem Verschachtelungsprozess geschrieben worden. Weitere Informationen finden Sie in der Spezifikation.
Es gibt aber Möglichkeiten, das Problem zu umgehen. Im Folgenden werden die drei Farbstile in &
eingehüllt, wodurch die Kaskadenreihenfolge beibehalten wird, wie es der Autor möglicherweise beabsichtigt hat. .card
-Elemente sind rot.
.card {
color: green;
& { color: blue; }
& { color: red; }
}
Es empfiehlt sich sogar, alle Stile, die nach dem Verschachtelungsprozess folgen, in &
einzufügen.
.card {
color: green;
@media (prefers-color-scheme: dark) {
color: lightgreen;
}
& {
aspect-ratio: 4/3;
}
}
Funktionserkennung
Es gibt zwei gute Möglichkeiten, CSS-Verschachtelungen zu erkennen: Sie können Verschachtelungen verwenden oder mit @supports
prüfen, ob die Auswahlmöglichkeit für Verschachtelungen geparst werden kann.
Vorteile von Verschachtelungen:
html {
.has-nesting {
display: block;
}
.no-nesting {
display: none;
}
}
mit @supports
:
@supports (selector(&)) {
/* nesting parsing available */
}
Mein Kollege Bramus hat ein sehr gutes Codepen, in dem diese Strategie veranschaulicht wird.
Debugging mit Chrome-Entwicklertools
Die aktuelle Unterstützung für Verschachtelungen in DevTools ist minimal. Derzeit werden Stile im Bereich „Stile“ wie erwartet dargestellt, aber das Verfolgen des Nestings und des vollständigen Auswahlkontexts wird noch nicht unterstützt. Wir haben ein Design und Pläne, um dies transparent und klar zu machen.
In Chrome 113 soll CSS-Verschachtelung zusätzlich unterstützt werden. Bleib also dran!
Die Zukunft
CSS-Verschachtelung ist erst in Version 1 verfügbar. Version 2 wird mehr syntaktische Vereinfachungen und möglicherweise weniger Regeln enthalten, die man sich merken muss. Es gibt viele Anfragen, dass das Parsen von verschachtelten Elementen nicht eingeschränkt sein oder Probleme verursachen soll.
Das Nesting ist eine große Verbesserung der CSS-Sprache. Sie hat Auswirkungen auf fast alle architektonischen Aspekte von CSS. Diese großen Auswirkungen müssen eingehend untersucht und verstanden werden, bevor Version 2 effektiv spezifiziert werden kann.
Zum Schluss noch eine Demo, in der @scope
, Verschachtelung und @layer
zusammen verwendet werden. Es ist alles sehr spannend!