What is the difference between :first-child and :first-of-type?
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 What is the difference between p:nth-child(2) and p:nth-of-type(2)?
CSS :first-child and :first-of-type (example)
Here's a great explanation on CSS Tricks. Basically, the first child of the #blog
div
is not an article
element; it's a header
element. :first-child
will match an element if it's the first element in the parent container. :first-of-type
will match an element if it's the first element of its type in the parent container regardless of whether or not there are other elements preceding it.
Is there a functional difference between *:first-child and :first-child?
They are identical even if we consider performance. From the specification we can read
If a universal selector represented by * (i.e. without a namespace prefix) is not the only component of a sequence of simple selectors selectors or is immediately followed by a pseudo-element, then the * may be omitted and the universal selector's presence implied.
So writing > :first-child
should mean the same as > *:first-child
for the browser.
You can also read
Note: it is recommended that the * not be omitted, because it decreases the potential confusion between, for example,
div :first-child
anddiv:first-child
. Here,div *:first-child
is more readable.
So it's not only a matter of preference but it helps avoid confusion and make the code more readable.
In the new sepcification we can also read:
Unless an element is featureless, the presence of a universal selector has no effect on whether the element matches the selector.
and
Note: In some cases, adding a universal selector can make a selector easier to read, even though it has no effect on the matching behavior. For example,
div :first-child
anddiv:first-child
are somewhat difficult to tell apart at a quick glance, but writing the former asdiv *:first-child
makes the difference obvious.
difference between :first and :first-child not clear
From Official Docs:
The :first pseudo-class is equivalent
to :eq(0). It could also be written as
:lt(1). While this matches only a
single element, :first-child can
match more than one: One for each
parent.
While :first
matches only a single element, the :first-child
selector can match more than one: one for each parent. This is equivalent to :nth-child(1)
.
http://api.jquery.com/first-selector/
Update:
Here is an example using :first-child
:
http://jsbin.com/olugu
You can view its soruce and edit yourself. If you replace :first-child
with :first
, it will only highlight the first word there. This is what is defined for them.
And here is example using :first
:
http://jsbin.com/olugu/2
Difference between nth-of-type(1) and first-of-type pseudo-classes
From the specification:
Same as
:nth-of-type(1)
. The:first-of-type
pseudo-class represents an element that is the first sibling of its type.
They are the same and we all agree with this BUT we may need them for different use cases.
Imagine the case where I need to write a SASS loop to create selector based on indexes. I will be using :nth-of-type
Ex:
@for $i from 1 through $n {
.container > div:nth-of-type(#{$i}) { ... }
}
And sometimes I only need to target the first element so I can simply use first-of-type
which will make the code easier to read.
first-child not selecting the first of its type
There is no element that has that class and is the first child. If you want the first element with that class, use .portfolio:first-of-type
.
How can I use first of type or fist child to target only the top level one. Not the nested one?
You won't be able to use :first-of-type or :first-child to target only the top level one and ignore the nested one.
Both these pseudo css selectors checks child for immediate parent.
For example, :first-of-type works as:
And :first-child works as:
Difference between div~div and div:not(:first-of-type)?
In terms of matching elements, there is no difference. Any div
that follows some other div
within the same parent is, by necessity, not the first element of type div
within its parent.
If the sibling selector were +
and not ~
, then div+div
has the added condition that the following element must appear immediately after the preceding element. This is not the case with ~
— any number of siblings of any other kind may appear between the two.
If the pseudo-class were :first-child
and not :first-of-type
, then div:not(:first-child)
will still match div:first-of-type
if the first div
within its parent is not its first child.
Here's an illustration:
<section>
<div></div> <!-- div:first-child or div:first-of-type -->
<div></div> <!-- div+div or div~div or div:nth-of-type(2) -->
<p></p>
<div></div> <!-- div+p+div or div~div or div:nth-of-type(3),
but not div+div -->
</section>
<section>
<h1></h1> <!-- h1:first-child -->
<div></div> <!-- div:first-of-type or div:nth-child(2) -->
<div></div> <!-- div~div or div:nth-of-type(2) or div:nth-child(3) -->
</section>
In terms of specificity, there is a difference. If you have CSS rules with both selectors matching the same elements, then div:not(:first-of-type)
will take precedence due to the :first-of-type
pseudo-class. Notice that the :not()
itself is not counted — only its argument is considered.
Here's another illustration:
div { float: left; width: 50px; height: 50px; margin: 5px; border: 1px solid red;}
/* 1 pseudo-class, 1 type -> specificity = 0-1-1 */div:not(:first-of-type) { border-color: green;}
/* 2 types -> specificity = 0-0-2 */div ~ div { border-color: blue;}
<section> <div></div> <div></div> <div></div></section>
What is the difference between p:nth-child(2) and p:nth-of-type(2)?
This question may remind you of What is the difference between :first-child and :first-of-type? — and in fact, a lot of parallels can be drawn between the two. Where this question greatly differs from the other is the arbitrary integer argument X, as in :nth-child(X)
and :nth-of-type(X)
. They're similar in principle to their "first" and "last" counterparts, but the potentially matching elements vary greatly based on what's actually in the page.
But first, some theory. Remember that simple selectors are independent conditions. They remain independent even when combined into compound selectors. That means that the p
neither is influenced by, nor influences, how :nth-child()
or :nth-of-type()
matches. Combining them this way simply means that elements must match all of their conditions simultaneously in order to match.
Here's where things get interesting. This independent matching means I can get pretty creative in how I express compound (and complex) selectors in terms of plain English, without changing the meaning of the selectors. In fact, I can do so right now in a way that makes the difference between :nth-child(2)
and :nth-of-type(2)
seem so significant that the pseudo-classes might as well be completely unrelated to each other (except for the "siblings" part anyway):
p:nth-child(2)
: Select the second child among its siblings if and only if it is ap
element.p:nth-of-type(2)
: Select the secondp
element among its siblings.
All of a sudden, they sound really different! And this is where a bit of explanation helps.
Any element may only have a single child element matching :nth-child(X)
for any integer X at a time. This is why I've chosen to emphasize "the second child" by mentioning it first. In addition, this child element will only match p:nth-child(X)
if it happens to be of type p
(remember that "type" refers to the tagname). This is very much in line with :first-child
and :last-child
(and, similarly, p:first-child
and p:last-child
).
There's two aspects to :nth-of-type(X)
on the other hand:
Because the "type" in
:nth-of-type()
is the same concept as the "type" in a type selector, this family of pseudo-classes is designed to be used in conjunction with type selectors (even though they still operate independently). This is whyp:nth-of-type(2)
can be expressed as succinctly as "Select the secondp
element among its siblings." It just works!However, unlike
:first-of-type
and:last-of-type
, the X requires that there actually be that many child elements of the same type within their parent element. For example, if there's only onep
element within its parent,p:nth-of-type(2)
will match nothing within that parent, even though thatp
element is guaranteed to matchp:first-of-type
andp:last-of-type
(as well as, by extension,p:only-of-type
).
An illustration:
<div class="parent">
<p>Paragraph</p>
<p>Paragraph</p> <!-- [1] p:nth-child(2), p:nth-of-type(2) -->
<p>Paragraph</p>
<footer>Footer</footer>
</div>
<div class="parent">
<header>Header</header>
<p>Paragraph</p> <!-- [2] p:nth-child(2) -->
<p>Paragraph</p> <!-- [3] p:nth-of-type(2) -->
<footer>Footer</footer>
</div>
<div class="parent">
<header>Header</header>
<figure>Figure 1</figure>
<p>Paragraph</p> <!-- [4] -->
<footer>Footer</footer>
</div>
<div class="parent">
<header>Header</header>
<p>Paragraph</p> <!-- [2] p:nth-child(2) -->
<figure>Figure 1</figure>
<hr>
<figure>Figure 2</figure> <!-- [5] .parent > :nth-of-type(2) -->
<p>Paragraph</p> <!-- [5] .parent > :nth-of-type(2) -->
<p>Paragraph</p>
<footer>Footer</footer>
</div>
What's selected, what's not, and why?
Selected by both
p:nth-child(2)
andp:nth-of-type(2)
The first two children of this element are bothp
elements, allowing this element to match both pseudo-classes simultaneously for the same integer argument X, because all of these independent conditions are true:- it is the second child of its parent;
- it is a
p
element; and - it is the second
p
element within its parent.
Selected by
p:nth-child(2)
only
This second child is ap
element, so it does matchp:nth-child(2)
.But it's the first
p
element (the first child is aheader
), so it does not matchp:nth-of-type(2)
.Selected by
p:nth-of-type(2)
only
Thisp
element is the secondp
element after the one above, but it's the third child, allowing it to matchp:nth-of-type(2)
but notp:nth-child(2)
. Remember, again, that a parent element can only have one child element matching:nth-child(X)
for a specific X at a time — the previousp
is already taking up the:nth-child(2)
slot in the context of this particular parent element.Not selected
Thisp
element is the only one in its parent, and it's not its second child. Therefore it matches neither:nth-child(2)
nor:nth-of-type(2)
(not even when not qualified by a type selector; see below).Selected by
.parent > :nth-of-type(2)
This element is the second of its type within its parent. Like:first-of-type
and:last-of-type
, leaving out the type selector allows the pseudo-class to potentially match more than one element within the same parent. Unlike them, how many it actually matches depends on how many of each element type there actually are.Here, there are two
figure
elements and threep
elements, allowing:nth-of-type(2)
to match afigure
and ap
. But there's only oneheader
, onehr
, and onefooter
, so it won't match elements of any of those types.
In conclusion, :nth-child()
and :nth-of-type()
, with an integer argument X (i.e. not in the form An+B with a coefficient A of n), function pretty similarly to :first-child
/:last-child
and :first-of-type
/:last-of-type
, with the major difference being that the argument, along with the page itself, influences how many different elements may be matched with :nth-of-type()
.
Of course, there's a whole lot more to :nth-child()
and :nth-of-type()
than just a simple integer argument, but needless to say the details and possibilities thereof are outside the scope of this question.
Related Topics
Extending Selectors from Within Media Queries with SASS
What Is the Correct "-Moz-Appearance" Value to Hide Dropdown Arrow of a <Select> Element
How to Identify Microsoft Edge Browser via CSS
Aligning Two Divs Side-By-Side
How Does #Iefix Solve Web Fonts Loading in IE6-IE8
Spin or Rotate an Image on Hover
Calc of Max, or Max of Calc in CSS
Bootstrap 4 Card-Deck with Number of Columns Based on Viewport
Css3 Transition on Click Using Pure CSS
Creating CSS Global Variables:Stylesheet Theme Management
Background Image for Select (Dropdown) Does Not Work in Chrome
Webkit CSS Animation Issue - Persisting the End State of the Animation
Div's VS. Tables or CSS VS. Being Stupid
Why Adding Version Number to CSS File Path
How to Vertically Middle-Align Floating Elements of Unknown Heights
Absolute VS Relative Position Width & Height