Abschnitt 2 · Lektion 5
Struktur mit Pseudoklassen
Die dritte Gruppe von Pseudoklassen fragt weder nach einem Zustand noch nach einem Attribut, sondern nach der Position im Baum. Damit lassen sich Dinge ausdrücken, für die man sonst beim Schreiben des Markups mitzählen müsste.
Erstes, letztes, einziges
<ul>
<li>Erster Punkt</li>
<li>Mittlerer Punkt</li>
<li>Letzter Punkt</li>
</ul>
<ul>
<li>Ganz allein</li>
</ul> li {
padding: 6px 0;
border-bottom: 1px solid #e4e4e7;
}
li:first-child {
font-weight: 700;
}
li:last-child {
border-bottom-style: none;
}
li:only-child {
color: #2563eb;
} :first-child trifft ein Element, das das erste Kind seines Elternteils ist. :last-child entsprechend das letzte, :only-child eines, das gar keine Geschwister hat.
Der häufigste Einsatz ist genau der aus dem Beispiel: eine Trennlinie unter jedem Listenpunkt, außer unter dem letzten. Ohne :last-child bräuchtest du dafür eine Extra-Klasse am letzten Eintrag, und die müsste jemand pflegen, sobald sich die Liste ändert.
Jedes zweite, jedes dritte
<table>
<tbody>
<tr><td>Zeile 1</td><td>a</td></tr>
<tr><td>Zeile 2</td><td>b</td></tr>
<tr><td>Zeile 3</td><td>c</td></tr>
<tr><td>Zeile 4</td><td>d</td></tr>
<tr><td>Zeile 5</td><td>e</td></tr>
<tr><td>Zeile 6</td><td>f</td></tr>
</tbody>
</table> td {
padding: 6px 16px;
}
/* Jede zweite Zeile */
tbody tr:nth-child(2n) {
background-color: #fafafa;
}
/* Jede dritte, beginnend mit der ersten */
tbody tr:nth-child(3n+1) {
font-weight: 700;
}
/* Die vorletzte, von hinten gezählt */
tbody tr:nth-last-child(2) {
color: #b91c1c;
} :nth-child() ist der große Bruder. In die Klammer kommt eine Formel der Bauart an+b, und der Browser setzt für n nacheinander 0, 1, 2 und so weiter ein.
2n ergibt 0, 2, 4, 6, also jedes zweite Element. Die 0 trifft dabei nichts, gezählt wird ab 1 und ein nulltes Kind gibt es nicht. Für Zebrastreifen in Tabellen ist das der Standardweg. Dafür gibt es auch die Schlüsselwörter even und odd, die dasselbe lesbarer sagen.
3n+1 ergibt 1, 4, 7, also jedes dritte ab dem ersten. Das brauchst du, sobald ein Raster drei Spalten hat und die erste Spalte etwas Eigenes bekommen soll.
:nth-last-child() zählt von hinten. Nützlich, wenn die Zahl der Elemente nicht feststeht, du aber die letzten beiden meinst.
Eine Zahl ohne n trifft genau ein Element: :nth-child(3) ist das dritte Kind. Das ist die Kurzform, die man am häufigsten schreibt.
Der Fallstrick, der jeden einmal erwischt
<article>
<h2>Eine Überschrift steht davor</h2>
<p>Dieser Absatz ist NICHT das erste Kind.</p>
<p>Der zweite Absatz.</p>
</article> /* Trifft nichts: das erste Kind ist die Überschrift */
p:first-child {
color: #b91c1c;
}
/* Trifft: der erste Absatz unter seinesgleichen */
p:first-of-type {
font-size: 20px;
} Hier steckt der Fehler, wegen dem diese Lektion so ausführlich ist. Auf der Seite ist kein Absatz rot.
p:first-child heißt nicht “der erste Absatz”. Es heißt: ein Element, das erstens ein p ist und zweitens das erste Kind seines Elternteils. Im Beispiel ist das erste Kind die Überschrift, also trifft der Selektor nichts. Kein Fehler, keine Meldung, einfach keine Wirkung.
p:first-of-type fragt anders: das erste p unter den p-Geschwistern, egal was sonst noch davorsteht. Deshalb wird der erste Absatz größer.
Merk dir die Unterscheidung an dieser Frage: Zählt alles mit, oder nur meinesgleichen? :first-child zählt alles, :first-of-type nur die eigene Sorte. Dasselbe gilt für :last-of-type, :only-of-type und :nth-of-type().
Ausschließen mit :not()
<ul>
<li>Normal</li>
<li class="hervorgehoben">Hervorgehoben</li>
<li>Normal</li>
</ul> li:not(.hervorgehoben) {
color: #71717a;
} :not() dreht die Auswahl um. li:not(.hervorgehoben) trifft alle Listenpunkte außer denen mit dieser Klasse.
Das ist oft der kürzere Weg als zwei Regeln, von denen die zweite die erste wieder zurücknimmt. Statt “alle grau, dann die eine wieder schwarz” schreibst du direkt “alle außer der einen grau”, und dann steht auch nur eine Wahrheit in der Datei.
In die Klammer darf inzwischen eine ganze Liste: li:not(.a, .b) schließt beide aus. Ein Detail für Abschnitt 3: :not() zählt für die Stärke einer Regel so viel wie sein stärkstes Argument, nicht null.
Zum Mitnehmen
first-child heißt erstes Kind, nicht erster Absatz. Steht eine Überschrift davor, trifft p:first-child nichts.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 4 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.