Der Unterschied zwischen :nth-child und :nth-of-type

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Nehmen wir an, dieses HTML

<section>
   <p>Little</p>
   <p>Piggy</p>    <!-- We want this one -->
</section>

Diese tun genau dasselbe

p:nth-child(2) { color: red; }
p:nth-of-type(2) { color: red; }

Es gibt aber natürlich einen Unterschied.

Unser :nth-child-Selektor oben bedeutet in "einfacher Sprache", wähle ein Element aus, *wenn*

  1. es ein Paragraphenelement ist
  2. es das zweite Kind eines Elternelements ist

Unser :nth-of-type-Selektor bedeutet in "einfacher Sprache"

  1. Wähle das zweite Paragraphenkind eines Elternelements aus

:nth-of-type ist... wie kann man es am besten ausdrücken... *weniger bedingt*.

Nehmen wir an, unser Markup wurde zu diesem geändert

<section>
   <h1>Words</h1>
   <p>Little</p>
   <p>Piggy</p>    <!-- We want this one -->
</section>

Das bricht

p:nth-child(2) { color: red; } /* Now incorrect */

Das funktioniert immer noch

p:nth-of-type(2) { color: red; } /* Still works */

Mit "bricht" meine ich, dass der oben genannte :nth-child-Selektor jetzt das Wort "Little" anstelle von "Piggy" auswählt, weil dieses Element sowohl 1) das zweite Kind als auch 2) ein Paragraphenelement ist. Mit "funktioniert immer noch" meine ich, dass "Piggy" immer noch ausgewählt wird, weil es der zweite Paragraph unter diesem Elternelement ist.

Wenn wir ein <h2> nach diesem <h1> hinzufügen würden, würde der :nth-child-Selektor *gar nichts auswählen*, weil jetzt das zweite Kind kein Paragraph mehr ist, sodass der Selektor nichts findet. Der :nth-of-type funktioniert wieder, wie erwartet.

Ich finde, :nth-of-type ist weniger zerbrechlich und generell nützlicher, obwohl :nth-child häufiger vorkommt (meiner Meinung nach). Wie oft denkst du "Ich möchte das zweite Kind eines Elternelements auswählen, wenn es zufällig ein Paragraph ist." Möglicherweise manchmal, aber wahrscheinlicher möchtest du "den zweiten Paragraph auswählen" oder "jede dritte Tabellenzeile auswählen", was Fälle sind, in denen :nth-of-type (meiner Meinung nach) die stärkere Wahl ist.

Ich stelle fest, dass die meisten meiner "Mist, warum funktioniert dieser :nth-child-Selektor nicht?!"-Momente darauf zurückzuführen sind, dass sich herausstellt, dass ich den Selektor mit einem Tag versehen habe und das Kind mit der entsprechenden Nummer nicht wirklich dieses Tag hat. Wenn ich also :nth-child verwende, ist es meiner Erfahrung nach generell am besten, das Elternelement anzugeben und :nth-child ohne Tag-Qualifizierung zu belassen.

dl :nth-child(2) {  } /* is better than */
dd:nth-child(2) {  } /* this */

Aber natürlich hängt alles von der genauen Situation ab.

Die Browserunterstützung für :nth-of-type ist ziemlich gut... Firefox 3.5+, Opera 9.5+, Chrome 2+, Safari 3.1+, IE 9+.

Ich würde sagen, wenn Sie eine tiefere Unterstützung benötigen, würde jQuery Ihnen helfen (verwenden Sie den Selektor dort, weisen Sie eine Klasse zu und gestalten Sie mit dieser Klasse), aber tatsächlich hat jQuery die Unterstützung für :nth-of-type eingestellt. Das erscheint mir seltsam. Ich habe gehört, es lag an geringer Nutzung. Wenn Sie diesen Weg gehen möchten, hier ist ein Plugin, um sie zurückzubekommen. jQuery 1.9 unterstützt :nth-of-type jetzt wieder (bis IE 6), das ist also eine Option.

Verwandt: Vergessen Sie nicht die fantastischen Cousins :first-of-type, :last-of-type, :nth-last-of-type und :only-of-type. Erfahren Sie hier mehr.

Wenn Sie mit einem visuellen Beispiel experimentieren möchten, schauen Sie sich dieses Werkzeug an!