Pseudo- classes in CSS: Selecting Elements by Their Index

CSS also provides selectors for matching elements based on their position in the document subtree. These are known as child-indexed pseudo-classes, because they rely on the position or order of the element rather than its type, attributes, or ID. There are five:

  • :first-chiLd
  • :Last-child
  • :onLy-chiLd
  • :nth-chiLd()
  • :nth-Last-chiLd()

:first-child and :last-child

As you’ve probably guessed from the names, the :first-chiLd and :Last-chiLd pseudo­classes make it possible to select elements that are the first child or last child of a node (element). As with other pseudo-classes, :first-chiLd and :Last-chiLd have the fewest side effects when they’re part of a compound selector.

Let’s take a look at the HTML and CSS below:

<!DOCTYPE html>

<html lang=”en-US”>

<head>

<meta charset=”utf-8″>

<title>:first-child and :last-child</title>

<style type=”text/css”> body {

font: 16px / 1.5 sans-serif;

}

first-child {

color: #e91e63; /* hot pink */

}

:last-child {

color: #4caf50; /* green */

}

</style>

</head>

<body>

<h2>List of fruits</h2>

<ul>

<li>Apples</li>

<li>Bananas</li>

<li>Blueberries</li>

<li>Oranges</li>

<li>Strawberries</li>

</ul>

</body>

</html>

This code produces the result shown below. Using :first-child by itself matches more elements than we want.

Because :first-chiLd is unqualified, both the <h2> element and first <Li> element are hot pink. After all, <h2> is the first child of <body> , and the Apples <Li> is the first child of the <uL> element. But why are the remaining <Li> elements green? Well, that’s because :Last- chiLd is also unqualified, and <uL> is the last child of body. It’s effectively the same as typing *:first-chiLd and *:Last-chiLd .

If we qualify :first-chiLd and :Last-chiLd by adding a simple selector, it all makes more sense. Let’s limit our selection to list items. Change :first-chiLd to Li:first-chiLd and : Last-chiLd to Li:Last-chiLd . The result is shown below.

:only-child

The :onLy-chiLd pseudo-class matches elements if they’re the only child of another element. In the following example, we have two parent <div> elements and their child elements. The first <div> contains one item, while the second contains three:

<div>

<span class=”fruit”>Apple</span>

</div>

<div>

<span class=”fruit”>Banana</span>

<span class=”vegetable”>Spinach</span>

<span class=”vegetable”>Okra</span>

</div>

Using .fruit:onLy-chiLd {color: #9c27b0; /* violet */} will match <span cLass=”fruit”>AppLe</span> , since it’s the only child of the first <div> . None of the items in the second <div> match, however, because there are three siblings. You can see what this looks like below.

:nth-child() and :nth-last-child()

The ability to select the first and last children of a document is fine. But what if we want to select odd or even elements instead? Perhaps we’d like to pick the sixth element in a document subtree, or apply styles to every third element. This is where the :nth-child() and the :nth-last-child() pseudo-classes come into play.

Like :not(), :nth-child() and :nth-last-child() are also functional pseudo-classes. They accept a single argument, which should be one of the following:

  • the odd keyword
  • the even keyword
  • an integer (such as 2 or 8)
  • an argument in the form An+B (where a is a step interval, b is the offset, and n is a variable representing a positive integer)

That last item has a degree of complexity. We’ll come back to it shortly.

The difference between :nth-child() and :nth-Last-chiLd() is the starting point. :nth- child() counts forward and :nth-Last-chiLd() counts backward. CSS indexes use counting numbers and start with one rather than zero.

Both :nth-chiLd() and :nth-Last-chiLd() are useful for alternating patterns. Creating zebra-striped table row colors is a perfect use case. The CSS that follows gives even- numbered table rows a light, bluish-gray background:

tr:nth-child(even) {

background: rgba(96, 125, 139, 0.1);

}

Here’s the result seen in the browser.

Changing :nth-chiLd() to :nth-Last-chiLd() inverts this banding, since the counting begins from the bottom.

How about trying some complex examples using more complex arguments? We’ll start with the document pictured below, which contains 20 <div> items.

With :nth-chiLd() and :nth-Last-chiLd() , we can select a single child at a particular position. We can select all of the children after a particular position, or we can select elements by multiples, with an offset. Let’s change the background color of the sixth item:

.item:nth-child(6) {

background: #e91e63; /* red */

}

This gives us the result below.

But what if we want to select every third element? Here’s where the An+B syntax comes in:

.item:nth-child(3n) {

background: #e91e63; /* red */

}

Again, A is a step interval. It’s kind of a multiplier for n , which starts at 0. So if A equals 3, then 3n would match every third element (the 3rd, 6th, 9th elements, and so on). That’s exactly what happens, as you can see below.

Matters become even more interesting when we use :nth-chiLd() and :nth-Last-chiLd() to select all elements after a certain point. Let’s try selecting all but the first seven elements:

.item:nth-child(n+8) {

background: #e91e63;

}

Here, there’s no step value. As a result, n+8 matches every element n beginning with the eighth element, as shown below.

We can also use the offset and step values to select every third element, starting with the fifth:

.item:nth-child(3n+5) {

background: #e91e63;

}

You can see the results of this selector below.

Source: Brown Tiffany B (2021), CSS , SitePoint; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *