Phần tử mẹ có thể có một hoặc nhiều phần tử con:
<div class="parent">
<div>Child</div>
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Trong số những đứa trẻ này, chỉ có một đứa có thể là đứa đầu tiên. Điều này được kết hợp bởi :first-child
:
<div class="parent">
<div>Child</div> <!-- :first-child -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Sự khác biệt giữa :first-child
và :first-of-type
là :first-of-type
phần tử sẽ khớp với phần tử đầu tiên của loại phần tử của nó, phần tử này trong HTML được thể hiện bằng tên thẻ của nó, ngay cả khi phần tử đó không phải là phần tử con đầu tiên của phần tử gốc . Cho đến nay, các yếu tố con mà chúng tôi đang xem xét đều là div
s, nhưng hãy chịu khó với tôi, tôi sẽ giải quyết vấn đề đó sau một chút.
Bây giờ, câu chuyện cũng đúng: bất kỳ :first-child
cũng là :first-of-type
do cần thiết. Vì con đầu tiên ở đây cũng là con đầu tiên div
, nó sẽ khớp với cả hai lớp giả, cũng như bộ chọn kiểu div
:
<div class="parent">
<div>Child</div> <!-- div:first-child, div:first-of-type -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Bây giờ, nếu bạn thay đổi loại con đầu tiên từ div
một cái gì đó khác, chẳng hạn như h1
, nó sẽ vẫn là con đầu tiên, nhưng div
rõ ràng nó sẽ không còn là con đầu tiên nữa ; thay vào đó, nó trở thành cái đầu tiên (và duy nhất) h1
. Nếu có bất kỳ div
phần tử nào khác theo sau phần tử con đầu tiên này trong cùng một phần tử gốc, phần tử đầu tiên trong số các div
phần tử đó sau đó sẽ khớp div:first-of-type
. Trong ví dụ đã cho, con thứ hai trở thành con đầu tiên div
sau khi con đầu tiên được đổi thành 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>
Lưu ý rằng :first-child
tương đương với :nth-child(1)
.
Điều này cũng ngụ ý rằng mặc dù bất kỳ phần tử nào có thể chỉ có một phần tử con duy nhất phù hợp :first-child
tại một thời điểm, nhưng nó có thể và sẽ có số lượng phần tử con phù hợp với lớp :first-of-type
giả bằng số loại phần tử con mà nó có. Trong ví dụ của chúng tôi, bộ chọn .parent > :first-of-type
(với giả định *
đủ điều kiện ngầm định :first-of-type
) sẽ khớp với hai phần tử, không chỉ một:
<div class="parent">
<h1>Child</h1> <!-- .parent > :first-of-type -->
<div>Child</div> <!-- .parent > :first-of-type -->
<div>Child</div>
<div>Child</div>
</div>
Điều tương tự cũng đúng đối với :last-child
và :last-of-type
: any :last-child
cũng cần thiết :last-of-type
, vì hoàn toàn không có phần tử nào khác theo sau nó trong phần tử cha của nó. Tuy nhiên, vì con cuối cùng div
cũng là con cuối cùng, nên h1
không thể là con cuối cùng, mặc dù thuộc loại cuối cùng.
:nth-child()
và :nth-of-type()
hoạt động rất giống nhau về nguyên tắc khi được sử dụng với một đối số nguyên tùy ý (như trong :nth-child(1)
ví dụ đã đề cập ở trên), nhưng chúng khác nhau ở chỗ số phần tử có thể được so khớp bởi :nth-of-type()
. Điều này được đề cập chi tiết trong Sự khác biệt giữa p: nth-child (2) và p: nth-of-type (2) là gì?