Styles are applied to a web page using CSS selectors; selectors which make it possible for you to target a specific element or sets of elements. Usually, when you are starting with CSS, you’ll make use of element selectors before pivoting to use classes and IDs.
As powerful as these selectors are, they can be quite limiting, making it impossible to select an element based on its state. If you’ve ever worked with frontend frameworks like React and Vue, you possibly understand what state means. I am not referring to the overall state of the application, but the state of elements within the HTML code.
The humble link is a simple example–it can be created using an anchor tag <a>
. The link can then have different states:
- before the link is clicked
- when a user hovers a mouse cursor over the link
- when the link has been visited
Selectors used to target elements depending on their state are called pseudo-classes. nth-child
and nth-of-type
are pseudo-classes which select an element based on its position (the position of the element is also considered a state). Let’s take a closer look.
How to Work with nth-child()
The nth-child
pseudo-class is used to select an element based on its position in a list of siblings. There are things to take note of here:
- Siblings: where a parent and children elements are present. In selecting a sibling you’re trying to target a specific child of the chosen parent. A
ul
and bunch ofli
are examples of parent and children elements. - The position of the element in the list of its siblings is determined by values that are passed to the pseudo-class.
We’ll be making use of the HTML code below to learn how nth-child
works.
<ul> <li>Ruby</li> <li>Python</li> <li>JavaScript</li> <li>Go</li> <li>PHP</li> <li>Scala</li> <li>Java</li> <li>Kotlin</li> <li>C++</li> <li>C</li> </ul>
There are two different ways of specifying the position of the element: the use of keywords and functional notations.
:nth-child(even/odd)
If using keywords you can specify elements whose position is either an even
or an odd
number, like this:
ul :nth-child(even) { color: red; } ul :nth-child(odd) { color: gray; }
This gives us the following:
:nth-child(2)
When we specify a particular number (like the 2 in this example), we're selecting the element in the list of siblings whose position matches the number we’ve passed. Here we’re targeting the second child of the unordered list.
ul { color: gray; } ul :nth-child(2) { color: red; }
You can probably imagine what the result looks like:
One common pitfall here is after specifying the element, you might add a new element (like a heading) to the parent without realising the selected element will change. To show this, let’s add a heading to the list like this:
<ul> <h3>Programming Languages</h3> <li>Ruby</li> <li>Python</li> <li>JavaScript</li> <li>Go</li> <li>PHP</li> <li>Scala</li> <li>Java</li> <li>Kotlin</li> <li>C++</li> <li>C</li> </ul>
Even though this is actually invalid use of HTML, browsers will still render it fine, and in this case the first li
element will be selected as it is now the second child of the unordered list.
:nth-child(An)
Okay, now we’re taking it up a notch. Here the elements (plural) we select will be determined using functional notation. n
denotes a counter and A
represents the size of the cycle, giving us a sequence. For example, when we pass 2, it will select elements in the sequence 2, 4, 6, and so on:
ul :nth-child(2n) { color: red; }
To see it in action, let’s go back to our HTML code and add a few items to the list. We’ll also make the list an ordered list so that we can clearly see the items’ numbers:
<ol> <li>Ruby</li> <li>Python</li> <li>JavaScript</li> <li>Go</li> <li>PHP</li> <li>Scala</li> <li>Java</li> <li>Kotlin</li> <li>C++</li> <li>C</li> <li>Cobol</li> <li>Fortran</li> </ol>
Our result is as follows:
:nth-child(An+B)
Here we’ve added an extra calculation to our cycles: +B
. The elements whose position in the list of siblings matches the pattern will get selected. We need to know how the calculation happens, so let’s try a functional notation like this:
ol { color: gray; } ol :nth-child(3n+1) { color: red; }
This will select the items whose position matches 1, 4, 7, 10, and so on:
The calculation starts counting from 0
, which is the default value of n
, and as such the elements to be styled will be calculated like this:
- First Element: 3(0) + 1 =
1
. - Second Element: 3(1) + 1 =
4
. - Third Element: 3(2) + 1 =
7
. - Fourth Element: 3(3) + 1 =
10
.
Think of it as an algebraic equation where the value of n
increases arithmetically, and the element to be styled is the result of the equation. Here is another example, which you can edit yourself to see what happens:
ol :nth-child(3n+2) { color: red; }
You can also use this method to select even numbers, using the formula:
ol :nth-child(2n+0) { color: red; }
And odd numbers can be selected using:
ol :nth-child(2n+1) { color: red; }
How to Work with nth-of-type()
In all the examples we have seen for the nth-child
pseudo-class, it is important to note that the goal is to select elements in a list of siblings. This does not take into account the element type. To ensure the selection is also scoped to a particular type, we can make use of the nth-of-type
pseudo-class.
To see this at work let’s edit the HTML code to look like this (again, this is technically misuse of HTML, but browsers will interpret it just fine:
<ol> <p>This is a first paragraph<p> <li>Ruby</li> <li>Python</li> <li>JavaScript</li> <li>Go</li> <li>PHP</li> <p>Here is a paragraph</p> <li>Java</li> <li>Kotlin</li> <li>C++</li> <li>C</li> <li>Cobol</li> <li>Fortran</li> </ol>
To select the li
elements whose position is an odd number, we can do this,
ol li:nth-of-type(odd) { color: red; }
which gives us:
To select the li
elements whose position is an even number, we would do
ol li:nth-of-type(even) { color: red; }
You may think that using nth-child would work just as effectively as long as you’re specifying the li
, for example:
ol li:nth-child(odd) { color: red; }
but that isn’t the case. Try it yourself!
Conclusion
These pseudo-classes come in handy when you have to select specific elements in a list of siblings. To learn more about them, check the MDN Web Docs for nth-child()
and nth-of-type()
.
More CSS Fundamentals
Learn more about CSS, and CSS selectors with these fundamental guides:
-
CSSWhat is CSS Specificity and How Does it Work?
-
Web DevelopmentThe 30 CSS Selectors You Must Memorize
-
CSS7 CSS Units You Might Not Know About
No comments:
Post a Comment