How to Use Nth-Child Correctly

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:

  1. Only <p> tags should be affected and,
  2. 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:

  1. Only elements with the class my-class should be affected and,
  2. 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:

Sample Image

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 has an+b-1 siblings before it in the document tree, for any
positive integer or zero value of n, 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



Leave a reply



Submit