Have you ever wanted to apply styles to certain child elements in your HTML but not others?
The nth-child
and nth-last-child
may be exactly the CSS selectors that you need!
What do they do?
These selectors make it possible for you to apply styles to specific children elements. Both of these selectors allow you to iterate over the child elements of an element and apply styles to any of them that match the argument you pass them.
Which one should I choose?
There's one key difference between the two: the order in which they count the child elements.
nth-child: This selector applies styles to the list of children, starting with the first child element until it reaches the last one.
nth-last-child: This selector behaves the same way, with the only difference being that it starts with the last child element and iterating until it reaches the first element.
What arguments can you pass these selectors?
You can pass a few different types of arguments to each of the selectors.
- a positive integer -
nth-child(3)
andnth-last-child(3)
-
odd
/even
-nth-child(odd)
andnth-last-child(odd)
- a mathematical expression in the form of
an+b
-nth-child(an+b)
andnth-last-child(an+b)
(e.g.2n-3
).
Each of them take this mathematical expression that you provide and, starting with n=0
and increasing it by 1 as it iterates, returns a list of element indices (or positions in the children “array”) that it should apply to.
Let's look at some examples and compare how each expression affects the elements for both nth-child
and nth-last-child
side-by-side.
Examples
We’ll have 1 parent element and 10 child elements to start (all outlined containers with no background color), like this:
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
.parent {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.parent div:nth-child(n+5) {
background-color: blue;
color: white;
}
.child {
width: 30px;
height: 30px;
margin: 10px;
border: 1px solid black;
display: flex;
align-items: center;
justify-content: center;
}
For the sections below, any of the children that get selected will get background-color: blue
.
NOTE: I've added numbers inside each of the boxes in the examples below only to help visualize the order that CSS counts those elements. The actual order of the elements on the page is the same in both cases.
To follow along and apply the values yourself, you can use this as a template.
3
This is the most straightforward example, since we’re specifically choosing a certain element. No real “math” gets done here, we’re just picking “the 3rd child element from whichever end the selector starts on”.
nth-child(3)
nth-last-child(3)
even
Whenever the position of element is even, apply the styles!
nth-child(even)
nth-last-child(even)
odd
And similarly, whenever the position of the element is odd, apply the styles.
nth-child(odd)
nth-last-child(odd)
n
Let’s start using n
. This is where things get a little math-involved.
- The iterator starts at
n=0
and the value of the expressionn
whenn=0
is just 0. However, there is no “element 0”, so no styles get applied. - The iterator increases to
n=1
. The value of the expressionn
whenn=1
is 1. So it will apply the defined styles to the 1st element. - When
n=2
, the value of the expressionn
is 2, so the 2nd element also gets styles applied.
As shown below, this is the case for every child element since n
just continues to positive infinity, so styles will be applied to all child elements, regardless of how many you add.
nth-child(n)
nth-last-child(n)
n+1
This is a slight variation from the one above, but all elements still get the styles applied. This is because when n=0
the value of n+1
becomes 1, meaning that the style gets applied to the 1st child, as shown below.
nth-child(n+1)
nth-last-child(n+1)
n+3
This is where we’ll start to see some variation. When n=0
, the value of n+3
is 3, meaning that the first child that gets styles applied is element 3.
nth-child(n+3)
nth-last-child(n+3)
n-1
Similar to how n+1
applied to all elements, so does n-1
. When n=0
, n-1
is -1. When n=1
, n-1
is 0. Starting with n=2
, the value of n-1
is 1 and increases by 1 each time, so all child elements to infinity will get selected.
nth-child(n-1)
nth-last-child(n-1)
n-3
Just like above, n=0
to n=3
all equal to negative numbers or 0, so no elements get selected. But at n=4
(when n-3
equals 1) and above, all positive numbers get selected, so every element will get styles applied.
nth-child(n-3)
nth-last-child(n-3)
3n
Let’s add in an a
value! This becomes a multiplier that allows you to skip elements. When n=0
the value of 3n
is 0, so no element gets selected. But when n=1
, the value of 3n
is 3, so the 3rd element gets styled applied. Then the 6th (at n=2
) and the 9th (at n=3
) and so on.
nth-child(3n)
nth-last-child(3n)
3n+1
Now let’s put it all together. If we add +1
, it takes the results of the expression 3n
that we did above and shifts the element the styles get applied to.
At n=0
, the value of 3n+1
is 1. At n=1
, the value of 3n+1
is 4.
nth-child(3n+1)
nth-last-child(3n+1)
-n
So far, we’ve only done positive values of a
. What if we make a
equal -1
?
We saw that the expression n
resulted in all elements getting selected. Inversely, the expression -n
results in no elements getting selected.
When n=0
, -n
equals 0. When n=1
, -n
equals -1. When n=2
, -n
equals -2. And so on. So no positive integers will ever get returned, meaning no elements will ever get selected.
nth-child(-n)
nth-last-child(-n)
-n+3
If we add something to -n
however, we’ll be able to select some elements.
At n=0
, -n+3
equals 3. At n=1
, -n+3
equals 2. At n=2
, -n+3
equals 1. But once n=3
or higher, the value of -n+3
becomes either 0 or negative, so those won’t select any of the child elements.
This is a cool trick because it allows us to say I only want to select the:
- (in the case of
nth-child
) first child elements - (in the case of
nth-last-child
) last child elements
nth-child(-n+3)
nth-last-child(-n+3)
-n-3
What if we subtract from -n
? The result is very similar to the expression -n
itself, since no values of n
will ever result in -n-3
being positive. At n=0
, -n-3
is -3. At n=1
, -n-3
is -4. And so on.
nth-child(-n-3)
nth-last-child(-n-3)
-2n+6
Let’s go back to adding to -n
but also add a multiplier. This will let us use that same pattern of “only the first x elements in the list”, but allow us to skip over some between them.
At n=0
, -2n+6
equals 6, so the 6th element gets selected. At n=1
, -2n+6
equals 4. At n=2
, -2n+6
equals 2. Once you hit n=3
, the value of the expression is 0 and then following values are negative. So this becomes an effective way to say “For the first x styles in the list, apply styles to every other one.”
nth-child(-2n+6)
nth-last-child(-2n+6)
TL;DR
The important thing to remember when thinking about nth-child
vs nth-last-child
is that given the same expression (e.g. 2n+3
), the selectors will act very similarly. As you saw from each of the examples above, the images are basically mirrored versions of each other.
The only difference is whether they apply styles from the beginning (nth-child) of the list of child elements or the end (nth-last-child).
To learn more about these selectors with deeper technical explanations, see the w3 documentation.
Thanks for reading, and let me know if you have any questions in the comments!
Top comments (0)