В чем разница между: first-child и: first-of-type?

124

Я не могу отличить element:first-childиelement:first-of-type

Например, у вас есть div

div:first-child
→ Все <div>элементы, которые являются первыми дочерними элементами своего родителя.

div:first-of-type
→ Все <div>элементы, которые являются первым <div>элементом своего родителя.

Это похоже на одно и то же, но они работают по-разному.

Может кто-нибудь объяснить?

BoltClock
источник
Первый дочерний элемент нацелен только на первого дочернего элемента родителя, где первый из типов нацелен на первого дочернего элемента этого типа (div, диапазон или что-то еще, что вы пытаетесь нацелить)
Huangism
У первого дочернего элемента div может быть старший брат или сестра. first-of-type выбирает такой div, поскольку это первый дочерний элемент типа, first-child не будет выбирать этот div, потому что это не первый дочерний элемент.
n8bar

Ответы:

207

Родительский элемент может иметь один или несколько дочерних элементов:

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

Среди этих детей только один может быть первым. Этому соответствует :first-child:

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

Разница между :first-childи :first-of-typeзаключается в том, что :first-of-typeон соответствует первому элементу своего типа элемента, который в HTML представлен его именем тега, даже если этот элемент не является первым дочерним элементом родительского элемента . Пока что все дочерние элементы, на которые мы смотрим, были div, но потерпите меня, я вернусь к этому чуть позже.

А пока верно и обратное: любое :first-child- тоже :first-of-typeпо необходимости. Поскольку первый дочерний элемент здесь также является первым div, он будет соответствовать обоим псевдоклассам, а также селектору типа div:

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

Теперь, если вы измените тип первого дочернего элемента с divна что-то другое, например h1, он все равно будет первым дочерним элементом , но, divочевидно , он больше не будет первым ; вместо этого он становится первым (и единственным) h1. Если divпосле этого первого дочернего элемента в пределах того же родителя есть какие-либо другие divэлементы, тогда будет совпадать первый из этих элементов div:first-of-type. В данном примере второй дочерний элемент становится первым divпосле того, как первый дочерний элемент изменен на 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>

Обратите внимание, что :first-childэто эквивалентно :nth-child(1).

Это также означает, что, хотя у любого элемента может быть только один соответствующий дочерний элемент :first-childза раз, он может и будет иметь столько дочерних элементов, соответствующих :first-of-typeпсевдоклассу, сколько типов дочерних элементов у него есть. В нашем примере селектор .parent > :first-of-type(с неявной *квалификацией :first-of-typeпсевдо) будет соответствовать двум элементам, а не только одному:

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

То же самое верно и для :last-childand :last-of-type: any также :last-childявляется обязательным :last-of-type, поскольку за ним не следует ни один другой элемент в пределах своего родителя. Тем не менее, поскольку последний divтакже является последним ребенком, он h1не может быть последним ребенком, несмотря на то, что он последний в своем типе.

:nth-child()и :nth-of-type()работают очень похоже в принципе при использовании с произвольным целочисленным аргументом (как в :nth-child(1)примере, упомянутом выше), но где они различаются, так это в потенциальном количестве элементов, которым соответствуют :nth-of-type(). Это подробно описано в разделе В чем разница между p: nth-child (2) и p: nth-of-type (2)?

BoltClock
источник
4
Я наконец понял. Если бы я хотел, чтобы первый div был под элементом div, я бы назвал div: first-of-type, потому что над ним могут быть элементы, отличные от div. Это немного сбивало с толку, но теперь я понимаю. Это отличный и очень информативный пост. Спасибо за вашу помощь.
1
Я создал образец на основе этого ответа: codepen.io/bigtinabang/pen/pmMPxO
Тина Чен
14

Я создал пример, чтобы продемонстрировать разницу между first-childиfirst-of-type здесь.

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

Чтобы увидеть полный пример, посетите https://jsfiddle.net/bwLvyf3k/1/

Вен
источник
0

Разницу между типом first-child и first-child можно понять на примере. Вам нужно понять следующий пример, созданный мной, и он действительно работает, вы можете вставить коды в свой редактор, вы поймете, что это такое и как они работают

Код №1 для первокурсников:

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

результат

.p1, .p2, .p3 будут стилизованы, и их цвет будет красным. даже если мы поместим .p1 после второго div, он будет красным.

Код №2 для первенца:

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

результат:

если мы поместим .p2 после второго div 2, он не будет красным, однако в первом случае он работал.

Очистить все
источник