What is the difference between :first-child and :first-of-type?
CssCss SelectorsCss Problem Overview
I can't tell the difference between element:first-child
and element:first-of-type
For example say, you had a div
div:first-child
→ All <div>
elements that are the first child of their parent.
div:first-of-type
→ All <div>
elements that are the first <div>
element of their parent.
This seems like the exact same thing, but they work differently.
Could someone please explain?
Css Solutions
Solution 1 - Css
A parent element can have one or more child elements:
<div class="parent">
<div>Child</div>
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Among these children, only one of them can be the first. This is matched by :first-child
:
<div class="parent">
<div>Child</div> <!-- :first-child -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
The difference between :first-child
and :first-of-type
is that :first-of-type
will match the first element of its element type, which in HTML is represented by its tag name, even if that element is not the first child of the parent. So far the child elements we're looking at have all been div
s, but bear with me, I'll get to that in a bit.
For now, the converse also holds true: any :first-child
is also :first-of-type
by necessity. Since the first child here is also the first div
, it will match both pseudo-classes, as well as the type selector div
:
<div class="parent">
<div>Child</div> <!-- div:first-child, div:first-of-type -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Now, if you change the type of the first child from div
to something else, like h1
, it will still be the first child, but it will no longer be the first div
obviously; instead, it becomes the first (and only) h1
. If there are any other div
elements following this first child within the same parent, the first of those div
elements will then match div:first-of-type
. In the given example, the second child becomes the first div
after the first child is changed to an 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>
Note that :first-child
is equivalent to :nth-child(1)
.
This also implies that while any element may only have a single child element matching :first-child
at a time, it can and will have as many children matching the :first-of-type
pseudo-class as the number of types of children it has. In our example, the selector .parent > :first-of-type
(with an implicit *
qualifying the :first-of-type
pseudo) will match two elements, not just one:
<div class="parent">
<h1>Child</h1> <!-- .parent > :first-of-type -->
<div>Child</div> <!-- .parent > :first-of-type -->
<div>Child</div>
<div>Child</div>
</div>
The same holds true for :last-child
and :last-of-type
: any :last-child
is by necessity also :last-of-type
, since absolutely no other element follows it within its parent. Yet, because the last div
is also the last child, the h1
cannot be the last child, despite being the last of its type.
:nth-child()
and :nth-of-type()
function very similarly in principle when used with an arbitrary integer argument (as in the :nth-child(1)
example mentioned above), but where they differ is in the potential number of elements matched by :nth-of-type()
. This is covered in detail in https://stackoverflow.com/questions/52493178/what-is-the-difference-between-pnth-child2-and-pnth-of-type2
Solution 2 - Css
I have created an example to demonstrate the difference between first-child
and first-of-type
here.
.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;
}
<div class="parent">
<p>Child</p>
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Solution 3 - Css
The difference between the first-child-type and first-child can be understand with the example.you need to understand the follwing example created by me and it really work you can paste the codes in your editor you will understand what they are and how they work
Code #1 for first-of-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>
result
.p1,.p2,.p3 will be styled and thier color will be red.even if we put .p1 after the second div it will be red.
Code #2 for first-child:
<!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>
result:
if we put the .p2 after the second div 2 it will not be red however in the first case it was working.
Solution 4 - Css
The :first-child
pseudo-class selects an element that is the first element among a group of sibling elements if it is the first child of its parent. On the other hand, :first-of-type
selects the first element of the specified type among a group of sibling elements regardless of whether it's the first child of its parent.