Du möchtest das erste Element mit einer bestimmten Klasse ansprechen und versuchst es mit :first-of-type. Der CSS-Code sieht zunächst plausibel aus, aber im Browser passiert nichts. Hier ein typisches Beispiel:
<div class="beitrag">
<p>Ein normaler Einleitungsabsatz.</p>
<p class="hinweis">Der erste Hinweis.</p>
<p class="hinweis">Ein weiterer Hinweis.</p>
</div>
Dazu kommt folgende CSS-Regel:
.hinweis:first-of-type {
border-left: 4px solid #007788;
}
Eigentlich soll der erste Absatz mit der Klasse .hinweis einen farbigen Rahmen bekommen. Der Selektor greift allerdings nicht.
Das Problem ist einfach: :first-of-type sucht nicht nach dem ersten Element mit einer bestimmten Klasse. Die Pseudoklasse betrachtet den HTML-Elementtyp. In diesem Fall sind alle drei Elemente Absätze vom Typ <p>. Der Einleitungsabsatz ist bereits das erste <p> innerhalb des Elternelements.
Um den Unterschied zu verstehen, müssen wir drei Dinge auseinanderhalten:
- die Position eines Elements unter allen Geschwistern,
- die Position unter Geschwistern desselben Elementtyps,
- die Position unter Geschwistern, die zu einem bestimmten Selektor passen.
Was macht :first-child?
Die Pseudoklasse :first-child spricht das erste Kindelement innerhalb eines Elternelements an.
<article>
<p>Dieser Absatz wird ausgewählt.</p>
<p>Dieser Absatz wird nicht ausgewählt.</p>
</article>
article > p:first-child {
font-weight: bold;
}
Der erste Absatz wird fett dargestellt, weil er zugleich das erste Kindelement des <article>-Elements ist.
Sobald vor dem Absatz ein anderes Element steht, sieht die Sache anders aus:
<article>
<h2>Überschrift</h2>
<p>Dieser Absatz ist nicht das erste Kind.</p>
</article>
Die Regel article > p:first-child greift nun nicht mehr. Das erste Kindelement ist die Überschrift. Der Absatz steht an zweiter Stelle.
Anders gesagt: p:first-child bedeutet nicht »wähle den ersten Absatz«. Es bedeutet:
Wähle einen Absatz, wenn dieser Absatz das erste Kindelement seines Elternelements ist.
first-child betrachtet also die Position unter allen Geschwisterelementen.
Was macht :first-of-type?
Bei :first-of-type spielt es keine Rolle, ob vorher ein anderer Elementtyp steht. Die Pseudoklasse sucht das erste Geschwisterelement mit demselben HTML-Tag.
Für das vorherige Beispiel funktioniert daher folgende Regel:
article > p:first-of-type {
font-weight: bold;
}
Obwohl vor dem Absatz eine Überschrift steht, ist er das erste <p> innerhalb des Artikels.
Auch ein Bild oder eine Liste vor dem Absatz würde daran nichts ändern:
<article>
<h2>Überschrift</h2>
<img src="titelbild.jpg" alt="">
<p>Das ist der erste Absatz.</p>
<p>Das ist der zweite Absatz.</p>
</article>
article > p:first-of-type {
font-weight: bold;
}
Die Überschrift ist ein <h2>, das Bild ein <img> und der Absatz ein <p>. Für p:first-of-type werden nur die Absätze miteinander verglichen. Der erste Absatz wird daher ausgewählt.
Der häufige Irrtum mit Klassen
An dieser Stelle lauert das eigentliche Missverständnis:
.hinweis:first-of-type
Dieser Selektor bedeutet nicht:
Wähle das erste Element mit der Klasse
.hinweis.
Er bedeutet sinngemäß:
Wähle ein Element mit der Klasse
.hinweis, wenn es zugleich das erste Geschwisterelement seines HTML-Typs ist.
Schauen wir noch einmal auf das Beispiel vom Anfang:
<div class="beitrag">
<p>Ein normaler Einleitungsabsatz.</p>
<p class="hinweis">Der erste Hinweis.</p>
<p class="hinweis">Ein weiterer Hinweis.</p>
</div>
Der erste Hinweis besitzt zwar die Klasse .hinweis, ist aber nicht das erste <p>. Diese Position ist bereits durch den Einleitungsabsatz belegt.
Deshalb passt keines der beiden Hinweis-Elemente auf .hinweis:first-of-type.
Das kann sogar noch etwas verwirrender werden. Befinden sich etwa ein <p class="hinweis"> und ein <div class="hinweis"> im selben Elternelement, kann der Selektor theoretisch beide auswählen. Sofern jedes Element das erste Geschwister seines jeweiligen Elementtyps ist.
first-of-type bezieht sich eben auf den Tag-Namen und nicht auf eine CSS-Klasse.
Das erste Element mit einer bestimmten Klasse auswählen
Für diesen Fall gibt es inzwischen eine passende CSS-Lösung:
:nth-child(1 of .hinweis) {
border-left: 4px solid #007788;
}
Noch besser ist es, den Selektor auf den gewünschten Container zu begrenzen:
.beitrag > :nth-child(1 of .hinweis) {
border-left: 4px solid #007788;
}
Die Ergänzung of .hinweis sorgt dafür, dass vor dem Zählen zunächst alle Geschwister ohne diese Klasse ausgefiltert werden. Anschließend wählt 1 das erste passende Element aus.
Im Beispiel wird der erste Hinweis angesprochen, obwohl vor ihm ein normaler Absatz steht.
Der Unterschied wird besonders deutlich, wenn wir die Klasse vor die Pseudoklasse setzen:
.hinweis:nth-child(1)
Diese Regel wählt ein Element nur aus, wenn es die Klasse .hinweis besitzt und gleichzeitig das erste Kindelement ist.
Dagegen bedeutet:
:nth-child(1 of .hinweis)
Betrachte nur Elemente mit der Klasse
.hinweisund wähle davon das erste aus.
Die of <selector>-Syntax ist Teil von Selectors Level 4. Sie wird von Safari seit Version 9 sowie von Chrome und Edge seit Version 111 und Firefox seit Version 113 unterstützt. Für aktuelle Browser ist sie damit gut einsetzbar. Musst du sehr alte Browser unterstützen, solltest du allerdings eine Alternative vorsehen.
Möchtest du umgekehrt alle passenden Elemente außer dem ersten ansprechen, kannst du ebenfalls mit dieser Syntax arbeiten:
.beitrag > :nth-child(n + 2 of .hinweis) {
margin-top: 1rem;
}
Hier werden der zweite Hinweis und alle weiteren Hinweise ausgewählt.
Vergleich auf einen Blick
| Selektor | Wählt aus |
|---|---|
:first-child | das erste Kindelement eines Elternelements |
p:first-child | ein <p>, wenn es das erste Kindelement ist |
p:first-of-type | das erste <p> unter den Geschwistern |
.hinweis:first-of-type | ein .hinweis, wenn er zugleich der erste seines Elementtyps ist |
:nth-child(1 of .hinweis) | das erste Geschwisterelement mit der Klasse .hinweis |
Als kleine Eselsbrücke:
first-childfragt: »Stehst du ganz vorne?«first-of-typefragt: »Bist du der erste Vertreter deines HTML-Tags?«nth-child(1 of .klasse)fragt: »Bist du das erste Element, das zu diesem Selektor passt?«
Praxisbeispiel aus WordPress
Nehmen wir an, innerhalb eines WordPress-Artikels befinden sich mehrere Bilder. Das erste links oder rechts ausgerichtete Bild soll einen besonderen Abstand bekommen.
Das vereinfachte HTML sieht so aus:
<div class="entry-content">
<img src="bild-1.jpg" alt="">
<img class="alignleft" src="bild-2.jpg" alt="">
<img class="alignright" src="bild-3.jpg" alt="">
</div>
Ein Versuch mit :first-of-type führt nicht zum gewünschten Ergebnis:
.entry-content > img.alignleft:first-of-type,
.entry-content > img.alignright:first-of-type {
margin-top: 0;
}
Alle drei Elemente sind vom Typ <img>. Das erste Bild besitzt aber weder die Klasse .alignleft noch .alignright.
Die beiden Selektoren prüfen jeweils, ob ein ausgerichtetes Bild gleichzeitig das erste <img> ist. Das trifft auf keines der Bilder zu.
Mit der of-Syntax lässt sich die Auswahl präziser formulieren:
.entry-content > :nth-child(1 of img.alignleft, img.alignright) {
margin-top: 0;
}
Der Browser betrachtet nun nur Bilder, die entweder .alignleft oder .alignright besitzen. Von diesen passenden Bildern wird das erste ausgewählt: in unserem Beispiel bild-2.jpg.
Hinweis: Der Selektor setzt voraus, dass die Bilder direkte Kindelemente von .entry-content sind. Wenn dein Theme oder ein WordPress-Block zusätzliche Container ausgibt, musst du den Selektor an das tatsächliche HTML anpassen. Ein Blick in die Entwicklerwerkzeuge des Browsers erspart hier häufig einiges an Herumprobieren.
Wann eine zusätzliche Klasse einfacher ist
Die moderne CSS-Syntax ist praktisch, aber nicht automatisch für jedes Projekt die beste Lösung. Wenn du das HTML selbst kontrollierst, kann eine eindeutige Klasse verständlicher sein:
<p class="hinweis hinweis-erster">Der erste Hinweis.</p>
.hinweis-erster {
border-left: 4px solid #007788;
}
Auch bei dynamischen WordPress-Ausgaben lohnt sich ein Blick auf den PHP-Code, das Block-Markup oder das verwendete Template. Kann das gewünschte Element dort zuverlässig gekennzeichnet werden, ist eine zusätzliche Klasse oft robuster als ein komplizierter Selektor.
Lange Rede, kurzer Sinn
Der Unterschied zwischen den Selektoren lässt sich auf drei kurze Aussagen reduzieren:
first-child betrachtet die Position eines Elements unter allen Geschwistern.
first-of-type betrachtet die Position unter Geschwistern desselben HTML-Elementtyps.
Möchtest du dagegen das erste Element auswählen, das zu einer Klasse oder einem anderen Selektor passt, ist :nth-child(1 of .klasse) die präzisere Lösung.
Und wenn du das HTML kontrollieren kannst, bleibt eine eindeutige zusätzliche Klasse häufig die einfachste Variante. Nicht jede CSS-Aufgabe muss auf der Suche nach dem heiligen Selektor-Gral unnötig kompliziert werden. 🤓

