</> HTML5Advent
ENFRESDEITPT

// css · Web Platform Advent #7

Natives CSS-Nesting: der &-Selektor, Browser-Support und Unterschiede zu Sass

Verschachteltes CSS ohne Präprozessor schreiben. Wie der &-Verschachtelungsselektor funktioniert, wo er sich von Sass unterscheidet und welche Browser ihn heute unterstützen.

Ein ausgedrucktes Blatt mit HTML-Markup und einem darauf liegenden Stift

CSS-Nesting erlaubt es, Regeln innerhalb anderer Regeln zu schreiben, sodass zusammengehörende Stile beieinanderbleiben. Jahrelang war das nur mit einem Präprozessor wie Sass möglich. Jetzt ist es ein natives CSS-Feature, das in jedem modernen Browser läuft — ganz ohne Build-Schritt.

Die Grundidee

Statt den Eltern-Selektor für jedes Kind zu wiederholen, verschachtelst du die Kind-Regel in ihm. Diese beiden Blöcke liefern dasselbe Ergebnis:

/* Flat, traditional CSS */
.card { padding: 1rem; }
.card h2 { margin: 0; }
.card p { color: #555; }

/* Nested */
.card {
  padding: 1rem;
  h2 { margin: 0; }
  p { color: #555; }
}

Jeder verschachtelte Selektor wird relativ zu seinem Elternteil gelesen, sodass .card p das ist, was der Browser tatsächlich anwendet.

Der & Verschachtelungsselektor

Das Kaufmanns-Und & verweist auf den Eltern-Selektor. Du brauchst es immer dann, wenn der verschachtelte Selektor direkt am Elternteil ansetzen muss, statt einen Nachfahren zu beschreiben — Pseudoklassen, Modifikatorklassen und zusammengesetzte Selektoren:

.btn {
  background: #2563eb;

  &:hover { background: #1d4ed8; }   /* .btn:hover */
  &.is-active { background: #1e40af; } /* .btn.is-active */
}

Ohne das & würde ein bloßes :hover als Nachfahre behandelt: .btn *:hover, was fast nie das ist, was du willst. Wenn du einen verschachtelten Selektor schreibst, der mit einem Element oder einer Klasse beginnt (wie p oben), fügt der Browser implizit einen Nachfahren-Kombinator für dich ein.

Source code on a dark editor showing function blocks nested inside curly braces
Verschachtelung spiegelt die Struktur wider, die bereits in deinem Code steckt: Blöcke innerhalb geschweifter Klammern, eingerückt, um zu zeigen, was wozu gehört.

Media Queries verschachteln

Du kannst @media (und andere At-Regeln) innerhalb eines Selektors verschachteln und so responsive Anpassungen direkt neben der Regel halten, die sie verändern:

.sidebar {
  width: 100%;

  @media (min-width: 768px) {
    width: 280px;
  }
}

Wo es sich von Sass unterscheidet

Die Syntax sieht aus wie Sass, doch beide sind nicht identisch. Die Unterschiede, die am häufigsten zubeißen:

  • Verkettung: Sass lässt dich Selektoren wie &__title (BEM) bauen. Natives CSS-Nesting verkettet nicht&__title ist ungültig. Du musst den vollständigen Klassennamen schreiben.
  • Kein Kompilierschritt: natives Nesting läuft im Browser, es gibt also nichts zu kompilieren und keine Source-Maps zu verwalten.
  • Spezifität von &: in nativem CSS verhält sich & wie :is() und nimmt die Spezifität des spezifischsten Selektors in der Elternliste an, was sich subtil vom Sass-Ergebnis unterscheiden kann.

Browser-Support und Fallback

Natives CSS-Nesting wird in aktuellen Versionen von Chrome, Edge, Firefox und Safari unterstützt. Frühe Implementierungen verlangten, dass der verschachtelte Selektor mit einem Symbol beginnt (du schriebst also & p statt p); die gelockerte Syntax, die einen bloßen Element-Selektor erlaubt, ist das, was in den heutigen Browsern ausgeliefert wird. Wenn du ältere Engines unterstützen musst, bleibe bei Sass oder PostCSS — das Plugin postcss-nesting kompiliert natives Nesting zu flachem CSS herunter.

Schnellreferenz

Du willstSchreibe
Nachfahre.card { p { ... } }
Pseudoklasse&:hover { ... }
Modifikatorklasse&.is-active { ... }
Responsive@media (...) { ... } verschachtelt
BEM-Verkettungnicht unterstützt — schreibe die vollständige Klasse

Natives Nesting nimmt einen der letzten großen Gründe weg, bei einem neuen Projekt zu einem Präprozessor zu greifen. Halte die Verschachtelung flach — zwei oder drei Ebenen — und deine Stylesheets bleiben lesbar, während die Beziehungen zwischen den Selektoren offensichtlich bleiben.