Verschachtelung

Durch das Verschachteln von CSS-Stilregeln können Sie Ihre Stylesheets besser organisieren, leichter lesbar machen und einfacher verwalten.

Übersicht

Nachdem Sie sich mit Selektoren vertraut gemacht haben, fragen Sie sich wahrscheinlich, wie Sie sie in Ihren Stylesheets besser organisieren können. Stellen Sie sich vor, Sie wenden Stile auf Elemente in einem „Feature“-Abschnitt Ihrer Website an. Mit der Verschachtelung können Sie diese Stile so in der .feature-Regel gruppieren:

.feature {
  button {
    color: blue;
  }

  .link {
    color: red;
  }

  .text {
    font-size: 1.3em;
  }
}

Das ist dasselbe, als würden Sie jeden Stil separat schreiben:

.feature button {
  color: blue;
}

.feature .link {
   color: red;
}

.feature .text {
   font-size: 1.3em;
}

Die Verschachtelung kann beliebig viele Ebenen umfassen.

.feature {
  .heading {
    color: blue;

    a {
      color: green;
    }
  }
}

Gruppieren und Beziehungen herstellen

Durch das Verschachteln können Sie Stilregeln prägnanter gruppieren und Beziehungen zwischen ihnen herstellen.

Die verschachtelte Regel wird standardmäßig als Nachfolgerkombinator mit der äußeren Regel verknüpft. Mit Selektoren für die verschachtelten Regeln können Sie die Beziehungen ändern.

/* targets headings that are siblings of the .feature element and come immediately after it */
.feature {
  + .heading {
    color: blue;
  }

/* targets all paragraphs that are direct children of the .feature element */
  > p {
    font-size: 1.3em;
  }
}

Explizite Beziehungen mit dem &-Selektor definieren

Sie können auch den Selektor & verwenden, um beim Verschachteln von Stilregeln expliziter zu sein. & ist ein Symbol für die übergeordnete Auswahl.

.feature {
 & button {
    color: blue;
  }
}

Das wäre dasselbe, als würden Sie die Stile so schreiben:

.feature button {
  color: blue;
}

Wann & erforderlich ist

Ohne & sind verschachtelte Selektoren untergeordnete Selektoren des übergeordneten Selektors. Um zusammengesetzte Selektoren zu bilden, & ist erforderlich.

.feature {
  &:last-child {
    /* Selects the .feature element that is the :last-child, equivalent to .feature:last-child */
  }
   
  & :last-child {
    /* Selects the :last-child inside of a .feature element, equivalent to .feature :last-child */
  }

  &.highlight {
    /* Selects .feature elements that also have a .highlight class, equivalent to .feature.highlight */
  }

  & .highlight {
     /* Selects elements inside of the .feature element with the class .highlight, equivalent to .feature .highlight */
  }
}

Sie können auch den Kontext ändern und die &-Auswahl am Ende oder auf beiden Seiten der untergeordneten Auswahl platzieren.


/* Targets buttons with an adjacent sibling button */
button {
  & + & {
    /* … */
  }
}
img {
  .my-component & {
    /* styles for images inside of `.my-component` ... */
  }
}

Im letzten Beispiel fügen wir Stile für Bilder innerhalb eines Elements mit der Klasse .my-component hinzu. Das kann nützlich sein, wenn Sie an einem Projekt arbeiten, in dem Sie einem Element kein class oder id hinzufügen können.

Schachtelung und Spezifität

Wie bei :is() wird bei diesem Selektor die Spezifität des Selektors mit der höchsten Spezifität in der Selektorliste des übergeordneten Elements übernommen.

#main-header,
.intro {
  & a {
    color: green;
  }
}

.intro a {
  color: blue;
}

Die erste Regel richtet sich an alle Links innerhalb der #main-header- und .intro-Elemente und weist ihnen eine grüne Farbe zu.

Mit der zweiten Regel wird versucht, dies zu überschreiben, damit Links innerhalb des .intro-Elements blau dargestellt werden.

Wenn wir uns die Spezifität der einzelnen Regeln ansehen, wird deutlich, warum das nicht funktioniert.

/* equivalent to :is(#main-header, .intro) a with a specificity of (1, 0, 1) */
#main-header,
.intro {
  & a {
    color: green;
  }
}

/* lower specificity of (0, 1, 1) */
.intro a {
  color: blue;
}

Da die erste Regel ein id in ihrer Selektorliste enthält und verschachtelte Regeln die Spezifität des Selektors mit der höchsten Spezifität übernehmen, hat sie eine höhere Spezifität als die zweite Regel. Die Links sind auch für a-Elemente grün, die sich nicht in einem Element mit dem Selektor #main-header befinden.

Ungültige Verschachtelung

Ähnlich wie bei :is() können mit dem Verschachtelungsselektor keine Pseudoelemente dargestellt werden.

blockquote, blockquote::before, blockquote::after {
  color: navy;

  & {
    border: 1px solid navy;
  }
}

Sie würden erwarten, dass sowohl das blockquote-Element als auch seine Pseudoelemente navy-farbigen Text und Rahmen haben, aber das ist nicht der Fall. Da mit dem Selektor & keine Pseudoelemente dargestellt werden können, werden die verschachtelten Rahmenstile nur auf das Blockzitat angewendet.

Wenn Sie zusammengesetzte Selektoren mit & und Typselektoren erstellen, muss der Typselektor ohne Leerzeichen zuerst angegeben werden.

/* valid css nesting */
.feature {
  p& {
    font-weight: bold;
  }
}

/* invalid css nesting */
.feature {
  &p {
    font-weight: bold;
  }
}

Diese Regel ermöglicht die Verwendung von CSS-Nesting zusammen mit Vorverarbeitungstools wie Sass. In Sass würde durch &p der übergeordnete Selektor an den verschachtelten Typselektor angehängt und das Ergebnis wäre .featurep.

At-Regeln verschachteln

Regeln für bedingte Preisvergleichsportal-Gruppen wie @container, @media, @supports und @layer können auch verschachtelt werden.

.feature {
  @media (min-width: 40em) {
    /* ... */
  }

  @container (inline-size > 900px) {
    /* ... */
  }
}

.feature {
  @supports (display: grid) {
    /* ... */
  }
}

.feature {
  @layer component {
    h2 {
      /* ... */
    }
  }
}

Wissen testen

Was stellt der Selektor & bei der Verwendung von CSS-Nesting dar?

Der verschachtelte untergeordnete Selektor
Falsch.
Die Auswahl des übergeordneten Elements
Richtig!
Selektor für das nächste gleichgeordnete Element
Falsch.

Sie können nur zwei Ebenen verschachteln.

Richtig
Falsch.
Falsch
Richtig!

Welche @-Regeln können verschachtelt werden?

@media
Richtig!
@container
Richtig!
@import
Falsch.
@supports
Richtig!
@layer
Richtig!