CSS-Verschachtelung

Eine unserer beliebtesten CSS-Präprozessorfunktionen ist jetzt in die Sprache integriert: verschachtelte Stilregeln.

Argyle
Adam Argyle

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.

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

Nachher
.nesting {
  color: hotpink;

  > .is {
    color: rebeccapurple;

    > .awesome {
      color: deeppink;
    }
  }
}

Versuchen Sie es im Browser.

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.

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

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:

Das bunte Raster aus Formen besteht nicht mehr aus Kreisen, sie sind nur sehr schwach im Hintergrund.
Demo testen

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:

Am bunten Raster der Formen stehen nur noch Kreise, alle anderen Formen sind fast unsichtbar.
Demo testen

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:

Im farbenfrohen Raster sind nur kleine und mittlere Formen sichtbar.
Demo testen
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:

Das bunte Raster ist jetzt einfarbig und zeigt nur rosa Formen.
Demo testen
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.

Screenshot der Codepen-Demo von Bramus, in der gefragt wird, ob Ihr Browser CSS-Verschachtelung unterstützt Unter dieser Frage befindet sich ein grünes Feld, das Unterstützung signalisiert.

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.

Screenshot der Verschachtelungssyntax in den Chrome-Entwicklertools.

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!

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