This question already has answers here:
CSS Child vs Descendant selectors
(8 answers)
Closed 8 years ago.
These appear to do the same things. I've never been sure what the difference is.
<style>
#a > b > i{
color: blue;
}
#b b i{
color: red;
}
</style>
<div id="a">
<b><i>text</i></b>
</div>
<div id="b">
<b><i>text</i></b>
</div>
There is difference.
The > is a child selector which selects only direct/immediate elements where as #a b i will select child elements at any depth inside the specified parent.
For your markup:
<div id="a">
<b><i>text</i></b>
</div>
<div id="b">
<b><i>text</i></b>
</div>
Both should work but still child selector is more appropriate in that situation. Consider this:
<div id="a">
<b><i>text</i></b>
</div>
<div id="b">
<b><i>text</i></b>
<b><i>text<div><span><i>text</i></span>></div></i></b>
</div>
In the above case though, the child selector will not be applied on <i> inside the span element in <div><span><i>text</i></span>></div>, which is not a direct child of <b>element.
More Info:
CSS Child Selectors
Right from the specs
Child
An element A is called the child of element B if and only if B is the parent of A.
Descendant
An element A is called a descendant of an element B, if either (1) A is a child of B, or (2) A is the child of some element C that is a descendant of B.
Related
This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Closed last month.
Good day all,
I have an a tag with class "WORKSHEET_block" and which is contained in 3 other div.
The css to style is (which does not work):
.WORKSHEET_block < .fc-daygrid-event-harness < .fc-daygrid-day-events < .fc-daygrid-day-frame {
background-color: green !important;
}
<div class="fc-daygrid-day-frame">
<div class="fc-daygrid-day-events">
<div class="fc-daygrid-event-harness">
<a class="WORKSHEET_block">My Value</a>
</div>
</div>
</div>
I know if it was the other way around from parent to child we would use ">" from the parent to the child.
Is there anywhere I can select the parent from the child?
.fc-daygrid-day-frame:has(.WORKSHEET_block) {
background-color: green;
}
<div class="fc-daygrid-day-frame">
<div class="fc-daygrid-day-events">
<div class="fc-daygrid-event-harness">
<a class="WORKSHEET_block">This is the child using the class</a>
</div>
</div>
</div>
<div class="fc-daygrid-day-frame">
<div class="fc-daygrid-day-events">
<div class="fc-daygrid-event-harness">
<a>this child does not have any class</a>
</div>
</div>
</div>
Using :has relative selector. I have inserted an extra HTML code it doesn't have a WORKSHEET_block class, so the style is not applying to it
This question already has answers here:
Is there a "previous sibling" selector?
(30 answers)
Closed last month.
Is there a way to select elements with CSS based on whether class A or class B precedes the element first? For example:
<parent>
<div> 1 </div>
<div class='A'></div>
<div> 2 </div>
<div class='B'></div>
<div> 3 </div>
<div> 4 </div>
<div class='A'></div>
<div> 5 </div>
</parent>
Is there a way to apply a style to divs 2 and 5 (divs preceded by class A before class B)
and another style to divs 3 and 4 (divs preceded by class B before class A)
?
I tried using the selectors .A ~ * and .B ~ * which almost works, but doesn't correctly apply to situations like div 5.
You can use the :has relational Pseudo-class to query for elements that has an upcoming .A sibling.
.A ~ div {
color: red;
}
.B ~ div:has(~ .A) {
color: green;
}
<div> 1 </div>
<div class='A'></div>
<div> 2 </div>
<div class='B'></div>
<div> 3 </div>
<div> 4 </div>
<div class='A'></div>
<div> 5 </div>
See https://developer.mozilla.org/en-US/docs/Web/CSS/:has#browser_compatibility for browser compatibility.
What is the difference between p:nth-child(2) and p:nth-of-type(2)?
As per W3Schools CSS Selector Reference:
p:nth-child(2): Selects every <p> element that is the second child of its parent.
p:nth-of-type(2): Selects every <p> element that is the second <p> element of its parent.
The difference seem to be child of its parent and <p> element of its parent.
If we are already mentioning the element type as <p> in both the cases and the keyword parent establishes a parent-child relation, so what can be the difference?
For p:nth-child(2) it selects the second element of its parent element if it's a paragraph whereas p:nth-of-type(2) will select the second paragraph of its parent element. If you are still confused let's make me clarify it for you. Consider the code snippet below:
<section>
<h1>Words</h1>
<p>Little</p>
<p>Piggy</p> <!-- Want this one -->
</section>
Here, p:nth-child(2) will select <p>Little</p> because it is the second child of its parent and it a paragraph element.
But, Here, p:nth-of-type(2) will select <p>Piggy</p> because it will select the second paragraph among all the paragraph of its parent.
Help from: https://css-tricks.com/the-difference-between-nth-child-and-nth-of-type/
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 a p element.
p:nth-of-type(2): Select the second p 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 why p:nth-of-type(2) can be expressed as succinctly as "Select the second p 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 one p element within its parent, p:nth-of-type(2) will match nothing within that parent, even though that p element is guaranteed to match p:first-of-type and p: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) and p:nth-of-type(2)
The first two children of this element are both p 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 a p element, so it does match p:nth-child(2).
But it's the first p element (the first child is a header), so it does not match p:nth-of-type(2).
Selected by p:nth-of-type(2) only
This p element is the second p element after the one above, but it's the third child, allowing it to match p:nth-of-type(2) but not p: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 previous p is already taking up the :nth-child(2) slot in the context of this particular parent element.
Not selected
This p 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 three p elements, allowing :nth-of-type(2) to match a figure and a p. But there's only one header, one hr, and one footer, 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.
p:nth-child(1): Means that is the first child of any parent and is of type paragraph.
p:nth-of-type (1): Means that is the first appearance of the type paragraph within any parent
p:nth-child(2){background:#f00;}
p:nth-of-type(2){background:#0f0;}
<div>
<div>first child</div>
<p>second child and first element of class "p"</p>
<p>third child and second element of class "p"</p>
<p>fourth child and third element of class "p"</p>
</div>
The other answers hightlighted the main difference between both selectors which is the fact that nth-child will consider all the elements inside the same container (siblings elements) and nth-of-type will consider all the elements with the same type inside the same container.
The :nth-child(an+b) pseudo-class notation represents an element that
has an+b-1 siblings before it in the document treeref
The :nth-of-type(an+b) pseudo-class notation represents an element that has an+b-1 siblings with the same expanded element name before it in the document treeref
From this we can add another important difference between both selectors which is the fact that nth-of-type is generally used with a tag selector whereas nth-child doesn't need a tag selector. In other words, nth-of-type can select more than one element but nth-child can select only one element. Adding a tag selector with nth-of-type will restrict the selection to one element and adding a tag selector to nth-child will simply add more restriction to the one element we are targeting.1
nth-child()
This selector will select the 2nd child of .container.
.container :nth-child(2) {
border:1px solid red;
}
<div class="container">
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
</div>
This is the same selector as above but we add a tag restriction: Find the 2nd child of .container, if it's a p tag then select it.
.container p:nth-child(2) {
border:1px solid red;
}
<div class="container">
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
</div>
If we change p with h1 nothing will be selected because the 2nd child isn't a h1:
.container h1:nth-child(2) {
border:1px solid red;
}
<div class="container">
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
</div>
nth-of-type()
This selector will select the 2nd p and the 2nd h1. nth-of-type will behave like nth-child after grouping elements by the same type.
.container :nth-of-type(2) {
border:1px solid red;
}
<div class="container">
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
</div>
So we select the 2nd child inside this:
<div class="container">
<p>aaa</p>
<p>aaa</p> <-- this one -->
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
</div>
Then the 2nd child inside this:
<div class="container">
<h1>title</h1>
<h1>title</h1> <-- this one -->
</div>
Adding a tag selector will simply restrict the selection to only one group of element:
.container p:nth-of-type(2) {
border:1px solid red;
}
.container h1:nth-of-type(2) {
border:1px solid green;
}
<div class="container">
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
</div>
If your container contains only one type of element both selectors will for sure give the same result but will not behave the same (i.e. the alogirthm behind will be different).
You may also notice that if you remove the tag selector from both you will also have the same result:
.container :nth-of-type(2) {
border:1px solid red;
}
.container :nth-child(2) {
color:red;
}
/* The below will also select the same
.container p:nth-child(2)
.container p:nth-of-type(2)
.container *:nth-child(2)
.container *:nth-of-type(2)
*/
<div class="container">
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
</div>
Another difference (this is a personal thought) may be the performance of both. nth-child can be faster since it consider all the siblings elements at once so it's like we will have one loop to check all the elements. nth-of-type need to consider different type of elements not at the same time so we will probably have more processing thus it's slower (This is my own conclusion based on how both works. I have no formal proof of it).
1: I am considering a selection inside one container using an integer within nth-child/nth-of-type.
Assume we have following HTML:
<div id="content">
<p>a1</p>
<span>a2</span>
<p>a3</p>
<span>a4</span>
</div>
1) #content p:nth-child(2) -- applies to 0 elements
because p:nth-child(2) requires it be the second child and that the tag is p, but actually the tag is a <span>.
2) #content *:nth-child(2) -- apples to <span>a2</span>
because *:nth-child(2) only requires it be the second child, not require the tag name. * can be any tag name.
3) #content p:nth-of-type(2) . -- applies to <p>a3</p>
because p:nth-of-type(2) means the second one in the <p> node list.
4) #content *:nth-of-type(2) . -- applies to <p>a3</p> and <span>a4</span>
because *:nth-of-type(2) only requires the second one in the same tag node list.
p:nth-child selector, in "Plain English," means select an element if:
It is a paragraph element
It is the second child of a parent (if second child of a parent is not <p> css will not effect)
p:nth-of-type selector, in "Plain English," means:
Select the second paragraph <p> child of a parent (care about <p>, just list up all child <p> and take )
.first p:nth-child(2) {
background: blue // this css not effect
}
.first p:nth-of-type(2) {
background: red
}
<div class="first">
<p>This is 1st paragraph</p>
<div>This is a div</div>
<p>This is 2nd paragraph</p>
</div>
As MDN says:
The :nth-child() CSS pseudo-class matches elements based on their position in a group of siblings.
That means that p:nth-child(2) will only capture <p> elements that are the second child of their parent.
However, p:nth-of-type(2) will capture <p> elements that are the second element of their parent, regardless of the element's index. This mean's an element can have 100 children and if the last child is the second paragraph element among its siblings, it will be affected by the styles listed.
Some things to keep in mind (that haven't already been said):
an element is nth-child(1) and nth-of-type(1)
This is always true.
an element is nth-child(2) and nth-of-type(2)
This is true when an element's first 2 children are of the same type.
an element is nth-child(3) and nth-of-type(2)
This is true when an element's 1st and 3rd children are of the same type, but the 2nd child is not.
an element is nth-child(2) and nth-of-type(3)
This is always false as an element that is the 3rd of its type can not be the 2nd child of it's parent.
Example:
p:nth-child(2) { color: red; }
p:nth-of-type(2) { background-color: yellow; }
<div>
<p>Paragraph 1</p> <!-- p:nth-child(1), p:nth-of-type(1) -->
<p>Paragraph 2</p> <!-- p:nth-child(2), p:nth-of-type(2) -->
<span></span>
</div>
<hr />
<div>
<p>Paragraph 1</p> <!-- p:nth-child(1), p:nth-of-type(1) -->
<span></span>
<p>Paragraph 2</p> <!-- p:nth-child(3), p:nth-of-type(2) -->
</div>
p:nth-child(2): This will select all <p> elements that are the second element inside their parent element. The first element can be any other element. e.g.
<div>
<h1>Title</h1>
<p>Paragraph</p> ** p:nth-child(2)
<p>Paragraph</p>
</div>
<div>
<p>Paragraph</p>
<p>Paragraph</p> ** p:nth-child(2)
<p>Paragraph</p>
</div>
<div>
<p>Paragraph</p>
<h1>Text</h1>
<p>Paragraph</p> ** None are selected
</div>
p:nth-of-type(2): This will select all <p> elements that are the second occurrence of a <p> element inside their parent element.
<div>
<h1>Title</h1>
<p>Paragraph</p>
<p>Paragraph</p> ** p:nth-of-type(2)
</div>
<div>
<h1>Title</h1>
<h2>Subtitle</h2>
<p>Paragraph</p>
<h2>Subtitle</h2>
<h2>Subtitle</h2>
<h2>Subtitle</h2>
<p>Paragraph</p> ** p:nth-of-type(2)
</div>
<div>
<h1>Title</h1>
<p>Paragraph</p> ** None are selected
</div>
This question already has answers here:
What does a space mean in a CSS selector? i.e. What is the difference between .classA.classB and .classA .classB? [duplicate]
(3 answers)
Closed 4 years ago.
i am trying to bind style in my css style using below format but its not working and i am learner for web development can some one help me please what is mistack?
css
.block-header.row.sample h1{
color: aqua;
}
html
<div class="block-header">
<div class="row sample">
<div class="col-sm-6">
<h1 class="page-title">Pending Approvals</h1>
</div>
</div>
</div>
The problem in your rule is that there are no spaces between your classes, which makes the selector any h1 element with the parent having classes block-header, row, and sample.
You would need to put spaces so that the selector knows these elements are nested inside each other:
.block-header .row.sample h1 {
color: aqua;
}
Learn more about how these selectors work from this FreeCodeCamp guide.
Your style rule is wrong, it should be: .block-header .row.sample h1 instead of .block-header.row.sample h1. When you have a style for an element that's a descendant of another one (in your case .row.sample is a child of .block-header) you should have the parent first, followed by a space (or > if it's a direct child) and then the descendant element, just like you're doing with the h1...
You can see it works with that simple change:
.block-header .row.sample h1{
color: aqua;
}
<div class="block-header">
<div class="row sample">
<div class="col-sm-6">
<h1 class="page-title">Pending Approvals</h1>
</div>
</div>
</div>
You can read more about selectors in mdn.
What is the difference between p:nth-child(2) and p:nth-of-type(2)?
As per W3Schools CSS Selector Reference:
p:nth-child(2): Selects every <p> element that is the second child of its parent.
p:nth-of-type(2): Selects every <p> element that is the second <p> element of its parent.
The difference seem to be child of its parent and <p> element of its parent.
If we are already mentioning the element type as <p> in both the cases and the keyword parent establishes a parent-child relation, so what can be the difference?
For p:nth-child(2) it selects the second element of its parent element if it's a paragraph whereas p:nth-of-type(2) will select the second paragraph of its parent element. If you are still confused let's make me clarify it for you. Consider the code snippet below:
<section>
<h1>Words</h1>
<p>Little</p>
<p>Piggy</p> <!-- Want this one -->
</section>
Here, p:nth-child(2) will select <p>Little</p> because it is the second child of its parent and it a paragraph element.
But, Here, p:nth-of-type(2) will select <p>Piggy</p> because it will select the second paragraph among all the paragraph of its parent.
Help from: https://css-tricks.com/the-difference-between-nth-child-and-nth-of-type/
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 a p element.
p:nth-of-type(2): Select the second p 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 why p:nth-of-type(2) can be expressed as succinctly as "Select the second p 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 one p element within its parent, p:nth-of-type(2) will match nothing within that parent, even though that p element is guaranteed to match p:first-of-type and p: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) and p:nth-of-type(2)
The first two children of this element are both p 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 a p element, so it does match p:nth-child(2).
But it's the first p element (the first child is a header), so it does not match p:nth-of-type(2).
Selected by p:nth-of-type(2) only
This p element is the second p element after the one above, but it's the third child, allowing it to match p:nth-of-type(2) but not p: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 previous p is already taking up the :nth-child(2) slot in the context of this particular parent element.
Not selected
This p 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 three p elements, allowing :nth-of-type(2) to match a figure and a p. But there's only one header, one hr, and one footer, 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.
p:nth-child(1): Means that is the first child of any parent and is of type paragraph.
p:nth-of-type (1): Means that is the first appearance of the type paragraph within any parent
p:nth-child(2){background:#f00;}
p:nth-of-type(2){background:#0f0;}
<div>
<div>first child</div>
<p>second child and first element of class "p"</p>
<p>third child and second element of class "p"</p>
<p>fourth child and third element of class "p"</p>
</div>
The other answers hightlighted the main difference between both selectors which is the fact that nth-child will consider all the elements inside the same container (siblings elements) and nth-of-type will consider all the elements with the same type inside the same container.
The :nth-child(an+b) pseudo-class notation represents an element that
has an+b-1 siblings before it in the document treeref
The :nth-of-type(an+b) pseudo-class notation represents an element that has an+b-1 siblings with the same expanded element name before it in the document treeref
From this we can add another important difference between both selectors which is the fact that nth-of-type is generally used with a tag selector whereas nth-child doesn't need a tag selector. In other words, nth-of-type can select more than one element but nth-child can select only one element. Adding a tag selector with nth-of-type will restrict the selection to one element and adding a tag selector to nth-child will simply add more restriction to the one element we are targeting.1
nth-child()
This selector will select the 2nd child of .container.
.container :nth-child(2) {
border:1px solid red;
}
<div class="container">
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
</div>
This is the same selector as above but we add a tag restriction: Find the 2nd child of .container, if it's a p tag then select it.
.container p:nth-child(2) {
border:1px solid red;
}
<div class="container">
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
</div>
If we change p with h1 nothing will be selected because the 2nd child isn't a h1:
.container h1:nth-child(2) {
border:1px solid red;
}
<div class="container">
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
</div>
nth-of-type()
This selector will select the 2nd p and the 2nd h1. nth-of-type will behave like nth-child after grouping elements by the same type.
.container :nth-of-type(2) {
border:1px solid red;
}
<div class="container">
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
</div>
So we select the 2nd child inside this:
<div class="container">
<p>aaa</p>
<p>aaa</p> <-- this one -->
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
</div>
Then the 2nd child inside this:
<div class="container">
<h1>title</h1>
<h1>title</h1> <-- this one -->
</div>
Adding a tag selector will simply restrict the selection to only one group of element:
.container p:nth-of-type(2) {
border:1px solid red;
}
.container h1:nth-of-type(2) {
border:1px solid green;
}
<div class="container">
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<h1>title</h1>
</div>
If your container contains only one type of element both selectors will for sure give the same result but will not behave the same (i.e. the alogirthm behind will be different).
You may also notice that if you remove the tag selector from both you will also have the same result:
.container :nth-of-type(2) {
border:1px solid red;
}
.container :nth-child(2) {
color:red;
}
/* The below will also select the same
.container p:nth-child(2)
.container p:nth-of-type(2)
.container *:nth-child(2)
.container *:nth-of-type(2)
*/
<div class="container">
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
<p>aaa</p>
</div>
Another difference (this is a personal thought) may be the performance of both. nth-child can be faster since it consider all the siblings elements at once so it's like we will have one loop to check all the elements. nth-of-type need to consider different type of elements not at the same time so we will probably have more processing thus it's slower (This is my own conclusion based on how both works. I have no formal proof of it).
1: I am considering a selection inside one container using an integer within nth-child/nth-of-type.
Assume we have following HTML:
<div id="content">
<p>a1</p>
<span>a2</span>
<p>a3</p>
<span>a4</span>
</div>
1) #content p:nth-child(2) -- applies to 0 elements
because p:nth-child(2) requires it be the second child and that the tag is p, but actually the tag is a <span>.
2) #content *:nth-child(2) -- apples to <span>a2</span>
because *:nth-child(2) only requires it be the second child, not require the tag name. * can be any tag name.
3) #content p:nth-of-type(2) . -- applies to <p>a3</p>
because p:nth-of-type(2) means the second one in the <p> node list.
4) #content *:nth-of-type(2) . -- applies to <p>a3</p> and <span>a4</span>
because *:nth-of-type(2) only requires the second one in the same tag node list.
p:nth-child selector, in "Plain English," means select an element if:
It is a paragraph element
It is the second child of a parent (if second child of a parent is not <p> css will not effect)
p:nth-of-type selector, in "Plain English," means:
Select the second paragraph <p> child of a parent (care about <p>, just list up all child <p> and take )
.first p:nth-child(2) {
background: blue // this css not effect
}
.first p:nth-of-type(2) {
background: red
}
<div class="first">
<p>This is 1st paragraph</p>
<div>This is a div</div>
<p>This is 2nd paragraph</p>
</div>
As MDN says:
The :nth-child() CSS pseudo-class matches elements based on their position in a group of siblings.
That means that p:nth-child(2) will only capture <p> elements that are the second child of their parent.
However, p:nth-of-type(2) will capture <p> elements that are the second element of their parent, regardless of the element's index. This mean's an element can have 100 children and if the last child is the second paragraph element among its siblings, it will be affected by the styles listed.
Some things to keep in mind (that haven't already been said):
an element is nth-child(1) and nth-of-type(1)
This is always true.
an element is nth-child(2) and nth-of-type(2)
This is true when an element's first 2 children are of the same type.
an element is nth-child(3) and nth-of-type(2)
This is true when an element's 1st and 3rd children are of the same type, but the 2nd child is not.
an element is nth-child(2) and nth-of-type(3)
This is always false as an element that is the 3rd of its type can not be the 2nd child of it's parent.
Example:
p:nth-child(2) { color: red; }
p:nth-of-type(2) { background-color: yellow; }
<div>
<p>Paragraph 1</p> <!-- p:nth-child(1), p:nth-of-type(1) -->
<p>Paragraph 2</p> <!-- p:nth-child(2), p:nth-of-type(2) -->
<span></span>
</div>
<hr />
<div>
<p>Paragraph 1</p> <!-- p:nth-child(1), p:nth-of-type(1) -->
<span></span>
<p>Paragraph 2</p> <!-- p:nth-child(3), p:nth-of-type(2) -->
</div>
p:nth-child(2): This will select all <p> elements that are the second element inside their parent element. The first element can be any other element. e.g.
<div>
<h1>Title</h1>
<p>Paragraph</p> ** p:nth-child(2)
<p>Paragraph</p>
</div>
<div>
<p>Paragraph</p>
<p>Paragraph</p> ** p:nth-child(2)
<p>Paragraph</p>
</div>
<div>
<p>Paragraph</p>
<h1>Text</h1>
<p>Paragraph</p> ** None are selected
</div>
p:nth-of-type(2): This will select all <p> elements that are the second occurrence of a <p> element inside their parent element.
<div>
<h1>Title</h1>
<p>Paragraph</p>
<p>Paragraph</p> ** p:nth-of-type(2)
</div>
<div>
<h1>Title</h1>
<h2>Subtitle</h2>
<p>Paragraph</p>
<h2>Subtitle</h2>
<h2>Subtitle</h2>
<h2>Subtitle</h2>
<p>Paragraph</p> ** p:nth-of-type(2)
</div>
<div>
<h1>Title</h1>
<p>Paragraph</p> ** None are selected
</div>