Un elemento genitore può avere uno o più elementi figlio:
<div class="parent">
<div>Child</div>
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Tra questi bambini, solo uno di loro può essere il primo. Questo è abbinato da :first-child
:
<div class="parent">
<div>Child</div> <!-- :first-child -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
La differenza tra :first-child
e :first-of-type
è che :first-of-type
corrisponderà al primo elemento del suo tipo di elemento, che in HTML è rappresentato dal nome del tag, anche se quell'elemento non è il primo figlio del genitore . Finora gli elementi figlio che stiamo guardando sono stati tutti div
s, ma abbi pazienza, ci arriveremo tra un po '.
Per ora, vale anche il contrario: qualsiasi :first-child
è anche :first-of-type
per necessità. Poiché il primo figlio qui è anche il primo div
, corrisponderà a entrambe le pseudo-classi, nonché al selettore di tipo div
:
<div class="parent">
<div>Child</div> <!-- div:first-child, div:first-of-type -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Ora, se cambi il tipo del primo figlio da div
a qualcos'altro, ad esempio h1
, sarà ancora il primo figlio, ma div
ovviamente non sarà più il primo ; invece, diventa il primo (e unico) h1
. Se ci sono altri div
elementi che seguono questo primo figlio all'interno dello stesso genitore, il primo di quegli div
elementi corrisponderà div:first-of-type
. Nell'esempio fornito, il secondo figlio diventa il primo div
dopo che il primo figlio è stato modificato in h1
:
<div class="parent">
<h1>Child</h1> <!-- h1:first-child, h1:first-of-type -->
<div>Child</div> <!-- div:nth-child(2), div:first-of-type -->
<div>Child</div>
<div>Child</div>
</div>
Nota che :first-child
è equivalente a :nth-child(1)
.
Ciò implica anche che mentre ogni elemento può avere un solo elemento figlio corrispondente :first-child
alla volta, può e avrà tanti figli che corrispondono alla :first-of-type
pseudo-classe quanti sono i tipi di figli che ha. Nel nostro esempio, il selettore .parent > :first-of-type
(con una *
qualificazione implicita dello :first-of-type
pseudo) corrisponderà a due elementi, non solo a uno:
<div class="parent">
<h1>Child</h1> <!-- .parent > :first-of-type -->
<div>Child</div> <!-- .parent > :first-of-type -->
<div>Child</div>
<div>Child</div>
</div>
Lo stesso vale per :last-child
e :last-of-type
: any :last-child
è anche per necessità :last-of-type
, poiché assolutamente nessun altro elemento lo segue all'interno del suo genitore. Tuttavia, poiché l'ultimo div
è anche l'ultimo figlio, il h1
non può essere l'ultimo figlio, nonostante sia l'ultimo del suo tipo.
:nth-child()
e :nth-of-type()
funzionano in modo molto simile in linea di principio quando vengono utilizzati con un argomento intero arbitrario (come :nth-child(1)
nell'esempio menzionato sopra), ma dove differiscono è nel numero potenziale di elementi corrispondenti :nth-of-type()
. Questo è trattato in dettaglio in Qual è la differenza tra p: nth-child (2) e p: nth-of-type (2)?