Jaka jest różnica między: first-child i: first-of-type?

124

Nie potrafię odróżnić element:first-childielement:first-of-type

Na przykład powiedz, że masz element div

div:first-child
→ Wszystkie <div>elementy, które są pierwszym dzieckiem swojego rodzica.

div:first-of-type
→ Wszystkie <div>elementy, które są pierwszym <div>elementem ich rodzica.

Wydaje się, że to dokładnie to samo, ale działają inaczej.

Czy mógłby ktoś wyjaśnić?

BoltClock
źródło
Pierwsze dziecko jest skierowane tylko na pierwsze dziecko rodzica, gdzie pierwszy typ jest skierowany na pierwsze dziecko tego typu (div lub span, czy cokolwiek to jest, na które próbujesz skierować)
Huangism
Pierwsze dziecko „div” może mieć starsze rodzeństwo. first-of-type wybiera taki element div, ponieważ jest pierwszym dzieckiem danego typu, first-child nie wybierze tego elementu div, ponieważ nie jest to pierwszy element potomny.
n8bar

Odpowiedzi:

207

Element nadrzędny może mieć jeden lub więcej elementów podrzędnych:

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

Wśród tych dzieci tylko jedno z nich może być pierwsze. Odpowiada temu :first-child:

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

Różnica pomiędzy :first-child i :first-of-typepolega na tym, :first-of-typeże dopasuje pierwszy element swojego typu elementu, który w HTML jest reprezentowany przez jego nazwę tagu, nawet jeśli ten element nie jest pierwszym elementem podrzędnym elementu nadrzędnego . Jak dotąd wszystkie elementy potomne, na które patrzymy, byłydiv s, ale proszę o cierpliwość, za chwilę do tego dojdę.

Na razie prawdą :first-childjest również odwrotność: każdy też jest:first-of-type z konieczności. Ponieważ pierwsze dziecko jest tutaj również pierwsze div, dopasuje zarówno pseudoklasy, jak i selektor typu div:

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

Teraz, jeśli zmienisz typ pierwszego dziecka z divna coś innego, na przykład h1, nadal będzie to pierwsze dziecko, ale divoczywiście nie będzie już pierwszym ; zamiast tego staje się pierwszym (i jedynym) h1. Jeśli są jakieś innediv po tym pierwszym dziecku w obrębie tego samego rodzica elementy, pierwszy z tych divelementów będzie pasował div:first-of-type. W podanym przykładzie drugie dziecko staje divsię pierwszym dzieckiem po zmianie pierwszego dziecka na 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>

Zauważ, że :first-childjest to równoważne z :nth-child(1).

Oznacza to również, że chociaż każdy element może mieć tylko jeden pasujący element podrzędny :first-childna raz, może i będzie miał tyle elementów potomnych pasujących do :first-of-typepseudoklasy, ile ma typów dzieci, które ma. W naszym przykładzie selektor .parent > :first-of-type(z niejawną *kwalifikacją :first-of-typepseudo) dopasuje dwa elementy, a nie tylko jeden:

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

To samo odnosi się do :last-childi :last-of-type: any :last-childjest również z konieczności :last-of-type, ponieważ absolutnie żaden inny element nie występuje w swoim rodzicu. Jednak ponieważ ostatnie divjest również ostatnim dzieckiem, plikh1 nie może być ostatnim dzieckiem, mimo że jest ostatnim w swoim rodzaju.

:nth-child()i :nth-of-type()działają w zasadzie bardzo podobnie, gdy są używane z dowolnym argumentem będącym liczbą całkowitą (jak w :nth-child(1)powyższym przykładzie), ale różnią się potencjalną liczbą elementów dopasowanych przez :nth-of-type(). Jest to szczegółowo omówione w artykule Jaka jest różnica między p: nth-child (2) a p: nth-of-type (2)?

BoltClock
źródło
4
Wreszcie rozumiem. Gdybym chciał, aby pierwszy element div znajdował się pod elementem div, nazwałbym div: first-of-type, ponieważ nad nim mogą znajdować się elementy inne niż div. To było trochę zagmatwane, ale teraz rozumiem. To doskonały i bardzo pouczający post. Dziękuję i bardzo doceniam twoją pomoc.
1
Utworzyłem próbkę na podstawie tej odpowiedzi: codepen.io/bigtinabang/pen/pmMPxO
Tina Chen
14

Stworzyłem przykład, aby zademonstrować różnicę między first-childi first-of-typetutaj.

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;
}

Aby zobaczyć pełny przykład, odwiedź https://jsfiddle.net/bwLvyf3k/1/

Wen
źródło
0

Różnicę między typem pierwszego dziecka i pierwszego dziecka można zrozumieć na przykładzie. Musisz zrozumieć następujący przykład stworzony przeze mnie i naprawdę działa, możesz wkleić kody w swoim edytorze, zrozumiesz, czym one są i jak oni pracują

Kod nr 1 dla pierwszego typu:

<!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>

wynik

.p1, .p2, .p3 będą stylizowane, a ich kolor będzie czerwony. nawet jeśli umieścimy .p1 po drugim div, będzie on czerwony.

Kod # 2 na pierwsze dziecko:

<!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>

wynik:

jeśli umieścimy .p2 po drugiej div 2, nie będzie on czerwony, jednak w pierwszym przypadku działał.

Wyczyść wszystko
źródło