CSS-Verschachtelung

Eine unserer bevorzugten CSS-Präprozessorfunktionen ist jetzt in die Sprache integriert: die Stilregeln für Verschachtelungen.

Adam Argyle
Adam Argyle

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.

Vorher
.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.

Nachher
.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Im Browser ausprobieren

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.

Ein buntes Raster mit kleinen und großen Kreisen, Dreiecken und Quadraten.

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:

Das bunte Raster der Formen hat keine Kreise mehr,
    sie sind im Hintergrund sehr schwach.
Demo testen

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:

Das farbige Raster der Formen enthält nur Kreise, alle anderen Formen sind nahezu unsichtbar.
Demo testen

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:

Im farbenfrohen Raster sind nur kleine und mittelgroße Formen zu sehen.
Demo testen
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:

Das farbenfrohe Raster ist jetzt monochrom und zeigt nur rosafarbene Formen.
Demo testen
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.

Screenshot von Bramuss Codepen-Demo mit der Frage, ob Ihr Browser CSS-Verschachtelungen unterstützt Unter dieser Frage befindet sich ein grünes Feld, das auf Unterstützung hinweist.

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.

Screenshot der Verschachtelungssyntax der Chrome-Entwicklertools.

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!

Eine helle Karte auf grauem Hintergrund. Die Karte hat einen Titel und Text, einige Aktionsschaltflächen und ein Bild im Cyber-Punk-Stil.