Kodokon kodokon.com

Moderne Selektoren: :has, :is, :where, fortgeschrittenes :nth-child

Nutze die neuen funktionalen Pseudoklassen, um anhand des Inhalts auszuwählen, Selektoren zu gruppieren, ohne die Spezifität aufzublähen, und komplexe Muster gezielt anzusprechen.

9 Min. · 3 Fragen

Diese Lektion in Kodokon öffnen

:is() und :where() gruppieren beide Selektoren, unterscheiden sich aber in einem entscheidenden Punkt: der Spezifität. :is(nav, .menu, #main a) übernimmt die Spezifität seines stärksten Arguments (hier die ID), selbst wenn nav derjenige ist, der zutrifft. :where() hat eine Spezifität von null, unabhängig von seinen Argumenten. Praktische Folge: :where() ist das ideale Werkzeug für Resets und die Standardstile eines Design-Systems, die jeder einfache Klassenselektor danach mühelos überschreiben kann.

CSS
:where(h1, h2, h3, h4) {
  margin-block: 0;
  line-height: 1.2;
}

:is(article, aside, section) :is(h2, h3) {
  font-family: var(--font-heading);
}

.prose :is(ul, ol) li + li {
  margin-top: 0.5em;
}
Gruppieren und die Spezifität steuern

:has() kehrt endlich die Leserichtung um: Der Selektor zielt auf das Host-Element, nicht auf das, was es enthält. .card:has(> img) wählt die Karte aus, die ein Bild als direktes Kind hat. Kombiniert mit Zustands-Pseudoklassen lässt es Informationen ohne JavaScript nach oben fließen: ein Label gestalten, wenn sein Feld ungültig ist, ein Formular, wenn ein Feld den Fokus hat, eine Tabellenzeile, wenn ihre Checkbox angehakt ist.

CSS
.field:has(input:invalid:not(:focus)) label {
  color: #dc2626;
}

.card:has(> img) {
  padding-top: 0;
}

tr:has(input[type="checkbox"]:checked) {
  background: #eef2ff;
}
Anhand von Inhalt oder internem Zustand auswählen

Bei :nth-child() gilt es, zwei Fähigkeiten zu festigen. Erstens das Lesen von An+B-Formeln: 2n (gerade), 2n+1 (ungerade), -n+3 (die ersten drei), n+4 (vom vierten bis zum Ende); der Bereich „vom 2. bis zum 5.“ wird durch Kombination von :nth-child(n+2):nth-child(-n+5) geschrieben. Zweitens die neuere of S-Syntax: :nth-child(2n of .visible) zählt nur unter den Kindern, die auf .visible passen, während .visible:nth-child(2n) alle Kinder zählt und danach filtert - zwei sehr unterschiedliche Ergebnisse, sobald andere Elemente dazwischen liegen.

CSS
tr:nth-child(odd) {
  background: #fafafa;
}

li:nth-child(-n + 3) {
  font-weight: 600;
}

li:nth-child(n + 2):nth-child(-n + 5) {
  border-top: 1px solid #e5e7eb;
}

.row:nth-child(2n of .visible) {
  background: #eef2ff;
}
An+B-Formeln und die of-S-Syntax

Wissenscheck

Stelle sicher, dass du die wichtigsten Punkte dieser Lektion behalten hast.

  1. Wie hoch ist die Spezifität von :where(#main, .nav, a)?
    • Die der ID, also (1,0,0)
    • Die Summe der drei Argumente
    • Null, unabhängig von den Argumenten
    • Die des Arguments, das tatsächlich zutrifft
  2. Was wählt .card:has(> img) aus?
    • Bilder, die direkte Kinder einer Karte sind
    • Karten, die ein Bild als direktes Kind enthalten
    • Karten, die im DOM nach einem Bild stehen
    • Alle Bilder, die Nachfahren von Karten sind
  3. In einer Liste, in der nur einige li-Elemente .visible tragen, was bewirkt li:nth-child(2n of .visible)?
    • Es zielt auf die geraden li-Elemente der Liste, die zusätzlich die Klasse .visible haben
    • Es zielt auf jedes zweite li, wobei nur die li.visible-Elemente gezählt werden
    • Es zielt auf die geraden li-Elemente und fügt ihnen dann die Klasse .visible hinzu