Quelle est la différence entre: first-child et: first-of-type?

124

Je ne peux pas faire la différence entre element:first-childetelement:first-of-type

Par exemple, disons que vous aviez un div

div:first-child
→ Tous les <div>éléments qui sont le premier enfant de leur parent.

div:first-of-type
→ Tous les <div>éléments qui sont le premier <div>élément de leur parent.

Cela semble être exactement la même chose, mais ils fonctionnent différemment.

Quelqu'un pourrait-il expliquer?

BoltClock
la source
Le premier enfant cible uniquement le premier enfant du parent, où le premier de type cible le premier enfant de ce type (div ou un span ou tout ce que vous essayez de cibler)
Huangism
Le premier enfant «div» peut avoir un frère plus âgé. first-of-type sélectionne un tel div puisqu'il s'agit du premier enfant du type, first-child ne sélectionnerait pas ce div car ce n'est pas le premier élément enfant.
n8bar

Réponses:

207

Un élément parent peut avoir un ou plusieurs éléments enfants:

<div class="parent">
  <div>Child</div>
  <div>Child</div>
  <div>Child</div>
  <div>Child</div>
</div>

Parmi ces enfants, un seul d'entre eux peut être le premier. Ceci correspond à :first-child:

<div class="parent">
  <div>Child</div> <!-- :first-child -->
  <div>Child</div>
  <div>Child</div>
  <div>Child</div>
</div>

La différence entre :first-childet :first-of-typeest qu'il :first-of-typecorrespondra au premier élément de son type d'élément, qui en HTML est représenté par son nom de balise, même si cet élément n'est pas le premier enfant du parent . Jusqu'à présent, les éléments enfants que nous examinons ont tous été des divs, mais soyez indulgents, j'y reviendrai dans un instant.

Pour l'instant, l'inverse est également vrai: tout :first-childest également :first-of-typepar nécessité. Puisque le premier enfant ici est également le premier div, il correspondra aux deux pseudo-classes, ainsi qu'au sélecteur de type div:

<div class="parent">
  <div>Child</div> <!-- div:first-child, div:first-of-type -->
  <div>Child</div>
  <div>Child</div>
  <div>Child</div>
</div>

Maintenant, si vous changez le type du premier enfant de divà quelque chose d'autre, comme h1, ce sera toujours le premier enfant, mais ce ne sera plus le premier divévidemment; au lieu de cela, il devient le premier (et le seul) h1. S'il y a d'autres divéléments suivant ce premier enfant dans le même parent, le premier de ces divéléments correspondra alors div:first-of-type. Dans l'exemple donné, le deuxième enfant devient le premier divaprès que le premier enfant est changé en 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>

Notez que cela :first-childéquivaut à :nth-child(1).

Cela implique également que bien qu'un élément ne puisse avoir qu'un seul élément enfant correspondant :first-childà la fois, il peut et aura autant d'enfants correspondant à la :first-of-typepseudo-classe que le nombre de types d'enfants qu'il possède. Dans notre exemple, le sélecteur .parent > :first-of-type(avec une *qualification implicite du :first-of-typepseudo) correspondra à deux éléments, pas seulement un:

<div class="parent">
  <h1>Child</h1>   <!-- .parent > :first-of-type -->
  <div>Child</div> <!-- .parent > :first-of-type -->
  <div>Child</div>
  <div>Child</div>
</div>

Il en va de même pour :last-childand :last-of-type: any l' :last-childest aussi par nécessité :last-of-type, puisque absolument aucun autre élément ne le suit dans son parent. Pourtant, comme le dernier divest aussi le dernier enfant, le h1ne peut pas être le dernier, bien qu'il soit le dernier de son type.

:nth-child()et :nth-of-type()fonctionnent de manière très similaire en principe lorsqu'ils sont utilisés avec un argument entier arbitraire (comme dans l' :nth-child(1)exemple mentionné ci-dessus), mais là où ils diffèrent, c'est dans le nombre potentiel d'éléments correspondant à :nth-of-type(). Ceci est traité en détail dans Quelle est la différence entre p: nth-child (2) et p: nth-of-type (2)?

BoltClock
la source
4
Je comprends enfin. Si je voulais le premier div sous un élément div, j'appellerais div: first-of-type, car il pourrait y avoir des éléments non div au-dessus. C'était un peu déroutant, mais je comprends maintenant. C'est un article excellent et très instructif. Merci et votre aide est grandement appréciée.
1
J'ai créé un échantillon basé sur cette réponse: codepen.io/bigtinabang/pen/pmMPxO
Tina Chen
14

J'ai créé un exemple pour démontrer la différence entre first-childet first-of-typeici.

HTML

<div class="parent">
  <p>Child</p>
  <div>Child</div>
  <div>Child</div>
  <div>Child</div>
</div> 

CSS

.parent :first-child {
  color: red;
}

.parent :first-of-type {
  background: yellow;
}

.parent p:first-child {
  text-decoration: line-through;
}

// Does not work
.parent div:first-child {
  font-size: 20px;
}
// Use this instead
.parent div:first-of-type {
  text-decoration: underline;
}
// This is second child regardless of its type
.parent div:nth-child(2) {
  border: 1px black solid;
}

Pour voir l'exemple complet, veuillez visiter https://jsfiddle.net/bwLvyf3k/1/

Wen
la source
0

La différence entre le type premier enfant et premier enfant peut être comprise avec l'exemple.vous devez comprendre l'exemple suivant créé par moi et cela fonctionne vraiment, vous pouvez coller les codes dans votre éditeur, vous comprendrez ce qu'ils sont et comment ils travaillent

Code n ° 1 pour le premier du type:

<!DOCTYPE html>
<html>
<head>
<title>clear everything</title>
<style>
p:first-of-type{
color:red;
}
</style>
<head>
<body>
<p class="p1">some text</p>
<div>
<p class="p2">some text</p>
<div>
<p class="p3">some text</p>
</div>
<p class="p4">some text</p>
</div>
<p class="p5">some text</p>
</body>
</html>

résultat

.p1, .p2, .p3 seront stylisés et leur couleur sera rouge, même si nous mettons .p1 après le deuxième div, il sera rouge.

Code # 2 pour le premier enfant:

<!DOCTYPE html>
<html>
<head>
<title>clear everything</title>
<style>
p:first-child{
color:red;
}
</style>
<head>
<body>
<p class="p1">some text</p>
<div>
<p class="p2">some text</p>
<div>
<p class="p3">some text</p>
</div>
<p class="p4">some text</p>
</div>
<p class="p5">some text</p>
</body>
</html>

résultat:

si nous mettons le .p2 après le deuxième div 2, il ne sera pas rouge mais dans le premier cas, il fonctionnait.

Tout effacer
la source