Verwendung von CSS-Nesting

Das CSS-Nesting Modul ermöglicht es Ihnen, Ihre Stylesheets so zu schreiben, dass sie leichter lesbar, modularer und wartungsfreundlicher sind. Da Sie nicht ständig Selektoren wiederholen, kann auch die Dateigröße reduziert werden.

CSS-Nesting unterscheidet sich von CSS-Präprozessoren wie Sass dadurch, dass es vom Browser verarbeitet wird und nicht von einem CSS-Präprozessor vorab kompiliert wird. Außerdem ähnelt beim CSS-Nesting die Spezifität des &-Nesting-Selektors der Funktion :is(); sie wird unter Verwendung der höchsten Spezifität in der zugehörigen Selektorenliste berechnet.

Dieser Leitfaden zeigt verschiedene Wege, das Nesting in CSS zu arrangieren.

Kind-Selektoren

Sie können CSS-Nesting verwenden, um Kind-Selektoren eines Elternelements zu erstellen, die dann dazu verwendet werden können, Kindelemente bestimmter Eltern zu targetieren. Dies kann mit oder ohne den &-Nesting-Selektor geschehen.

Es gibt bestimmte Fälle, in denen die Verwendung des &-Nesting-Selektors notwendig oder hilfreich sein kann:

  • Beim Zusammenfügen von Selektoren, wie z.B. der Verwendung von zusammengesetzten Selektoren oder Pseudoklassen.
  • Für die Rückwärtskompatibilität.
  • Als visueller Indikator zur Verbesserung der Lesbarkeit; beim Erkennen des &-Nesting-Selektors wissen Sie, dass CSS-Nesting verwendet wird.
css
/* Without nesting selector */
parent {
  /* parent styles */
  child {
    /* child of parent styles */
  }
}

/* With nesting selector */
parent {
  /* parent styles */
  & child {
    /* child of parent styles */
  }
}

/* the browser will parse both of these as */
parent {
  /* parent styles */
}
parent child {
  /* child of parent styles */
}

Beispiele

In diesen Beispielen, eines ohne und eines mit dem &-Nesting-Selektor, wird das <input> innerhalb des <label> anders gestaltet als das <input>, das ein Geschwisterelement eines <label> ist.

Ohne Nesting-Selektor

HTML
html
<form>
  <label for="name">Name:
    <input type="text" id="name" />
  </label>
  <label for="email">email:</label>
  <input type="text" id="email" />
</form>
CSS
css
input {
  /* styles for input not in a label  */
  border: tomato 2px solid;
}
label {
  /* styles for label */
  font-family: system-ui;
  font-size: 1.25rem;

  input {
    /* styles for input in a label  */
    border: blue 2px dashed;
  }
}
Ergebnis

Mit Nesting-Selektor

CSS
css
input {
  /* styles for input not in a label  */
  border: tomato 2px solid;
}
label {
  /* styles for label */
  font-family: system-ui;
  font-size: 1.25rem;

  & input {
    /* styles for input in a label  */
    border: blue 2px dashed;
  }
}
Ergebnis

Kombinatoren

CSS-Kombinatoren können auch mit oder ohne den &-Nesting-Selektor verwendet werden.

Beispiel

Nesting des Geschwister-Kombinators

In diesem Beispiel wird der erste Absatz nach jedem <h2> mit dem nächstes-Geschwister-Kombinator (+) unter Verwendung von CSS-Nesting anvisiert.

HTML
html
<h2>Heading</h2>
<p>This is the first paragraph.</p>
<p>This is the second paragraph.</p>
CSS
css
h2 {
  color: tomato;
  + p {
    color: white;
    background-color: black;
  }
}
/* this code can also be written with the & nesting selector */
/* 
h2 {
  color: tomato;
  & + p {
    color: white;
    background-color: black;
  }
}
*/
Ergebnis

Zusammengesetzte Selektoren

Beim Verwenden von zusammengesetzten Selektoren in verschachteltem CSS müssen Sie den &-Nesting-Selektor verwenden. Dies liegt daran, dass der Browser automatisch Leerzeichen zwischen Selektoren hinzufügt, die den &-Nesting-Selektor nicht verwenden.

Um ein Element mit class="a b" zu targetieren, ist der &-Nesting-Selektor erforderlich, da andernfalls das Leerzeichen den zusammengesetzten Selektor brechen würde.

css
.a {
  /* styles for element with class="a" */
  .b {
    /* styles for element with class="b" which is a descendant of class="a" */
  }
  &.b {
    /* styles for element with class="a b" */
  }
}

/* the browser parses this as */
.a {
  /* styles for element with class="a" */
}
.a .b {
  /* styles for element with class="b" which is a descendant of class="a" */
}
.a.b {
  /* styles for element with class="a b" */
}

Beispiel

Nesting und zusammengesetzte Selektoren

In diesem Beispiel wird der &-Nesting-Selektor verwendet, um zusammengesetzte Selektoren zu erstellen, um Elemente mit mehreren Klassen zu gestalten.

HTML
html
<div class="notices">
  <div class="notice">
    <h2 class="notice-heading">Notice</h2>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
  </div>
  <div class="notice warning">
    <h2 class="warning-heading">Warning</h2>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
  </div>
  <div class="notice success">
    <h2 class="success-heading">Success</h2>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
  </div>
</div>
CSS

Stile für .notices, um mit dem Flexbox-Layout eine Spalte zu erstellen.

css
.notices {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: 90%;
  margin: auto;
}

Im folgenden CSS-Code wird Nesting verwendet, um sowohl mit als auch ohne & zusammengesetzte Selektoren zu erstellen. Der Top-Level-Selektor definiert die grundlegenden Stile für Elemente mit class="notice". Der &-Nesting-Selektor wird dann verwendet, um zusammengesetzte Selektoren für Elemente mit entweder class="notice warning" oder class="notice success" zu erstellen. Zusätzlich kann die Verwendung von Nesting zur Erstellung zusammengesetzter Selektoren ohne explizite Verwendung von & im Selektor .notice .notice-heading::before gesehen werden.

css
.notice {
  width: 90%;
  justify-content: center;
  border-radius: 1rem;
  border: black solid 2px;
  background-color: #ffc107;
  color: black;
  padding: 1rem;
  .notice-heading::before {
    /* equivalent to `.notice .notice-heading::before` */
    content: "ℹ︎ ";
  }
  &.warning {
    /* equivalent to `.notice.warning` */
    background-color: #d81b60;
    border-color: #d81b60;
    color: white;
    .warning-heading::before {
      /* equivalent to `.notice.warning .warning-heading::before` */
      content: "! ";
    }
  }
  &.success {
    /* equivalent to `.notice.success` */
    background-color: #004d40;
    border-color: #004d40;
    color: white;
    .success-heading::before {
      /* equivalent to `.notice.success .success-heading::before` */
      content: "✓ ";
    }
  }
}
Ergebnis

Angefügter Nesting-Selektor

Der &-Nesting-Selektor kann auch an einen verschachtelten Selektor angefügt werden, was den Effekt hat, den Kontext umzukehren.

Dies kann nützlich sein, wenn wir Stile für ein Kindelement haben, die sich ändern, wenn einem Elternelement eine andere Klasse gegeben wird:

html
<div>
  <span class="foo">text</span>
</div>

Im Gegensatz zu:

html
<div class="bar">
  <span class="foo">text</span>
</div>
css
.foo {
  /* .foo styles */
  .bar & {
    /* .bar .foo styles */
  }
}

Beispiel

Anfügen des Nesting-Selektors

In diesem Beispiel gibt es 3 Karten, von denen eine hervorgehoben ist. Die Karten sind alle genau gleich, außer dass die hervorgehobene Karte eine alternative Farbe für die Überschrift hat. Durch das Anfügen des &-Nesting-Selektors kann der Stil für .featured .h2 im Stil für h2 genestet werden.

HTML
html
<div class="wrapper">
  <article class="card">
    <h2>Card 1</h2>
    <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
  </article>
  <article class="card featured">
    <h2>Card 2</h2>
    <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
  </article>
  <article class="card">
    <h2>Card 3</h2>
    <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
  </article>
</div>
CSS
css
.wrapper {
  display: flex;
  flex-direction: row;
  gap: 0.25rem;
  font-family: system-ui;
}

Im folgenden CSS erstellen wir die Stile für .card und .card h2. Dann nestet man im h2-Stilblock die .featured Klasse mit dem angefügten &-Nesting-Selektor, was einen Stil für .card :is(.featured h2) erstellt, was äquivalent ist zu :is(.card h2):is(.featured h2).

css
.card {
  padding: 0.5rem;
  border: 1px solid black;
  border-radius: 0.5rem;
  & h2 {
    /* equivalent to `.card h2` */
    color: slateblue;
    .featured & {
      /* equivalent to `:is(.card h2):is(.featured h2)` */
      color: tomato;
    }
  }
}
Ergebnis

Verschachtelte Deklarationsregel

Die verschachtelte Deklarationsregel besagt, dass CSS-Regeln in der Reihenfolge, in der sie im CSS-Dokument geschrieben sind, geparst werden.

Mit dem folgenden CSS:

css
.foo {
  background-color: silver;
  @media (screen) {
    color: tomato;
  }
  color: black;
}

Die background-color wird zuerst geparst und auf Silber gesetzt, dann wird die @media Regel evaluiert und schließlich die color.

Das CSSOM parst das CSS auf folgende Weise:

txt
↳ CSSStyleRule
  .style
    - background-color: silver
  ↳ CSSMediaRule
    ↳ CSSNestedDeclarations
      .style (CSSStyleDeclaration, 1) =
      - color: tomato
  ↳ CSSNestedDeclarations
    .style (CSSStyleDeclaration, 1) =
      - color: black

Beachten Sie, dass zur Erhaltung der Parsing-Reihenfolge alle Regeln vor dem Verschachteln als top-level CSSRules behandelt werden, während alle top-level Regeln nach dem Verschachteln als CSSNestedDeclarations dargestellt werden. Deshalb befindet sich das color-black in einer verschachtelten Deklaration, obwohl es im Originaldokument eine top-level Deklaration ist.

Hinweis: Unterstützung für die Regel wurde mit CSSNestedDeclarations hinzugefügt. Browser, die dieses Interface nicht unterstützen, können verschachtelte Regeln in der falschen Reihenfolge parsen.

Verkettung (ist nicht möglich)

In CSS-Präprozessoren wie Sass ist es möglich, Nesting zu verwenden, um Zeichenfolgen zu verketten, um neue Klassen zu erstellen. Dies ist bei CSS-Methodologien wie BEM gängig.

css
.component {
  &__child-element {
  }
}
/* In Sass this becomes */
.component__child-element {
}

Warnung: Dies ist mit CSS-Nesting nicht möglich: wenn ein Kombinator nicht verwendet wird, wird der verschachtelte Selektor als ein Typselektor behandelt. Das Zulassen von Verkettung würde dies brechen.

In zusammengesetzten Selektoren muss der Typselektor zuerst kommen. Das Schreiben von &Element (ein Typselektor) macht den CSS-Selektor und den gesamten Selektorblock ungültig. Da der Typselektor zuerst kommen muss, muss der zusammengesetzte Selektor als Element& geschrieben werden.

css
.my-class {
  element& {
  }
}

/* the browser parses this to become a compound selector */
.my-class {
}
element.my-class {
}

Ungültige verschachtelte Stilregeln

Wenn eine verschachtelte CSS-Regel ungültig ist, werden alle eingeschlossenen Stile ignoriert. Dies hat keine Auswirkungen auf die Eltern- oder vorherigen Regeln.

Im folgenden Beispiel gibt es einen ungültigen Selektor (% ist kein gültiges Zeichen für Selektoren). Die Regel, die diesen Selektor enthält, wird ignoriert, aber nachfolgende gültige Regeln nicht.

css
.parent {
  /* .parent styles these work fine */
  & %invalid {
    /* %invalid styles all of which are ignored */
  }
  & .valid {
    /* .parent .valid styles these work fine */
  }
}

Siehe auch