How to use nth-child correctly?
With
body:nth-child(2) {
color: red;
}
you are selecting the second body element which is simply not there, if you want to get the second p element in body you have to write:
body p:nth-child(2) {
color: red;
}
Here is a Fiddle
nth-child not targeting the correct element?
It's because the nth-child
selector does not mean it's the nth of that specific class. It means that it's the nth sibling overall.
So the nth-child(2)
refers to your .reuinIt
class, however, it does not also have the .test
class and therefore it does not receive any styling.
Your last .test
class is the nth-child(4)
however that has no styling rules applied.
If you'd like to see a working example, I've updated your fiddle here.
EXAMPLES
The :nth-child
The important thing to remember here is that the :nth-child
selector specifically targets HTML elements based on their index/position inside their containers/parent elements.
Have a look at the example below and take note of how the corresponding commented :nth-child
selector's index continues to increment regardless of the type of element it's targeting.
<div id="container">
<h1>Heading 1</h1> <!-- h1:nth-child(1) -->
<p>Paragraph 1</p> <!-- p:nth-child(2) -->
<p>Paragraph 2</p> <!-- p:nth-child(3) -->
<h2>Heading 2</h2> <!-- h2:nth-child(4) -->
<p>Paragraph 3</p> <!-- p:nth-child(5) -->
</div>
The :nth-of-type
The cool thing about :nth-of-type
is that it ignores all of the other elements that are not of the same type, i.e. if the element you are targeting is a <p>
, it will ignore all of the surrounding "non-<p>
" elements when calculating its index.
The below example will provide you with a basic understanding of the indexing rules that :nth-of-type
follows:
<div id="container">
<h1>Heading 1</h1> <!-- h1:nth-of-type(1) -->
<p>Paragraph 1</p> <!-- p:nth-of-type(1) -->
<p>Paragraph 2</p> <!-- p:nth-of-type(2) -->
<h2>Heading 2</h2> <!-- h2:nth-of-type(1) -->
<p>Paragraph 3</p> <!-- p:nth-of-type(3) -->
</div>
A little more complexity with :nth-of-type
It is however very important to remember that :nth-of-type
bases it's indexing values on the HTML Element Type regardless of the CSS Class you are using to call the property.
Have a look at the below example:
<div id="container">
<h1>Heading 1</h1> <!-- h1:nth-of-type(1) -->
<p class="my-class">Paragraph 1</p> <!-- .my-class:nth-of-type(1) -->
<p>Paragraph 2</p> <!-- p:nth-of-type(2) -->
<h2 class="my-class">Heading 2</h2> <!-- .my-class:nth-of-type(1) -->
<p class="my-class">Paragraph 3</p> <!-- .my-class:nth-of-type(3) -->
<h1 class="my-class">Heading 3</h1> <!-- .my-class:nth-of-type(2) -->
</div>
This example is a little more complex, but it helps if you see CSS Declarations as a sort of filtering rule. For example, if create a CSS declaration by typing:
p:nth-of-type(2) {
background-color: red;
}
I am essentially telling the browser 2 things:
- Only
<p>
tags should be affected and, - Only if they are the second
<p>
tags amidst their siblings
The difficulty comes in when I write CSS that looks like this:
.my-class:nth-of-type(1) {
background-color: red;
}
By not specifying an element type, my rule essentially reads with the following filter:
- Only elements with the class
my-class
should be affected and, - Only if those elements are the first sibling of their type of elements.
If were to apply the above CSS to the HTML in the example (see fiddle for working example), we would get an output that looks like this:
In the output above, you'll see that both the first <h2>
and the first <p>
elements were affected regardless of whether or not their siblings had the my-class
class name applied.
nth-child css selector not working correctly if we had br tag in sibling of children elements
The queries work as expected. When you run .div1>span:nth-child(2)
you are requesting for a span element that is the second child of its parent, in this case div1. Second child of div1 is a <br>
and therefore you get null.
As suggested by Hao Wu, you should use :nth-of-type
document.querySelector(".div1>span:nth-of-type(2)")
This will search for the second span
element that is a child of div1
console.log("i have 5 span children as well : ", document.querySelectorAll(".div1>span").length);
console.log("second span child is null : ", document.querySelector(".div1>span:nth-of-type(2)"));
console.log("third span child is second span element : ", document.querySelector(".div1>span:nth-of-type(3)").textContent);
console.log("select second element by another way: ", document.querySelectorAll(".div1>span")[1].textContent);
console.log("tag name of second child: ", document.querySelector(".div1>*:nth-child(2)").tagName);
html>body>div.div1>span:nth-of-type(2) {
color: blue;
}
<html>
<body>
<div class="div1">
<span>this is example text 1</span>
<br>
<span>this is example text 2</span>
<br>
<span>this is example text 3</span>
<br>
<span>this is example text 4</span>
<br>
<span>this is example text 5</span>
<br>
</div>
</body>
</html>
Using nth of type or nth-child to target elements?
You are telling css to find all divs inside the main div .price. And because all your divs inside .price contain another child div (v-list__tile) there is always a first div. When you target a 2nd or 3rd child, because there is no 2nd nor 3rd divs inside the divs with role: listitem then it all seems to work (but it's not). It was just chance that your structure was this one and that you had not more than one div at the end of your structure.
You will be able to achieve want you want If you target only the direct descender:
.price > div:nth-child(1) p{
border:1px solid #009FD4;
}
I hope this helps: https://css-tricks.com/child-and-sibling-selectors/
CSS nth-child for greater than and less than
:nth-child()
doesn't work on classes, it looks for the element itself. You'd need to wrap the .container
divs by a wrapper and use the following:
.wrapper div:nth-child(n+3) {
/* put your styles here... */
}
<div class="wrapper">
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>
</div>
Working Demo.
Clarifying on :nth-child()
Using .container:nth-child(n+3)
may or may not work. Because, :nth-child()
pseudo-class represents nth
child element matching the selector (.container
in this case).
If the .container
element isn't the nth-child of its parent, it won't be selected.
From the Spec:
The
:nth-child(an+b)
pseudo-class notation represents an element
that hasan+b-1
siblings before it in the document tree, for any
positive integer or zero value ofn
, and has a parent element.
Consider this example:
<div class="parent">
<div>1st</div>
<div>2nd</div>
<div>3rd</div>
<div class="container">4th</div>
<div class="container">5th</div>
<div class="container">6th</div>
<div>7th</div>
<div class="container">8th</div>
<div>9th</div>
</div>
In this case, .container:nth-child(2)
won't select the 2nd div.container
element (which has 5th
content). Because that element is not the 2nd child of its parent, in parent's children tree.
Also, .container:nth-child(n+3)
will select all the div.container
elements because n
starts from 0
for the first element in the parent's children tree, and the first div.container
is the 4th child of its parent.
n starts from 0
n = 0: (0 + 3) = 3 => 3rd element
n = 1: (1 + 3) = 4 => 4th element
n = 2: (2 + 3) = 5 => 5th element
...
Hence div.container:nth-child(n+3)
represents all the 3rd, 4th, 5th, ... child elements matching div.container
selector.
Online Demo.
nth-child doesnt apply background-color correctly in the table
If you want to add background-color
for every 2nd child (every even child: 2, 4, 6...), you need to use nth-child(even)
Check out this snippet of even
, odd
selectors.
:nth-child(2) doesn't work. :nth-child(1) and :nth-child(3) do
Here is an explanation of what went wrong. It was the result of your selector. The oddity in the way it played out was due to your html structure, and using querySelector.
div.rules :nth-child()
This will first target the <div class="rules">
element. Then, it will look for all elements which are the nth-child inside of that div because of the space between the two selectors. Following that, using
querySelector
will select the first element of the matched set.
This is why you ended up getting the first <div>
with :nth-child(1)
, because it in fact matched every single nth-child(1), but taking the first result was coincidentally the element you expected.
However, :nth-child(2)
matching every second child element was far too wide of a net, and ended up getting the second child in the first div, and since that was the first result, that was where the red background showed up.
The final curiosity of :nth-child(3)
seeming to actually hit the proper element was only because there is only one third child element in all of that html, and it was the one which you expected, although as explained for reasons other than assumed.
Related Topics
Why Does Display Inline-Block Match Height of Text
Skew The Shadow, Not The Content
Style Both Parent and Child Element in CSS
One CSS File or Individual CSS Files for Each Page
Can't Find a "Not Equal" CSS Attribute Selector
CSS3 Box Shadow Size - Percent Units
CSS- Webkit-Text-Stroke But Stroke Covers Font-Color
How to Pass a Parameter to a CSS Class Using Less
Only First Media Query Working
How to Apply CSS for Specific Chrome Version
CSS Background Image Not Appearing in Safari
How to Fix Hamburger Menu Animation
CSS: Is It Correct That Text Content of a Div Overflows into The Padding