Pseudo- classes in CSS: Selecting Elements of a Particular Type by Their Index

The pseudo-classes discussed in the previous section match elements if they occupy the given position in a document subtree. For instance, p:nth-Last-chiLd(2) selects every <p> element that’s the next-to-last element of its parent.

In this section, we’ll discuss typed child-indexed pseudo-classes. These pseudo-classes also match elements based on the value of their indexes, but matches are limited to elements of a particular type or tag name-such as selecting the fifth <p> element, or all even-indexed <h2> elements.

There are five such pseudo-classes with names that mirror those of their untyped counterparts:

  • :first-of-type I
  • :Last-of-type M
  • :onLy-of-type M
  • :nth-of-type()
  • :nth-last-of-type()

The difference between these and child-indexed pseudo-classes is a subtle one. Where p:nth-child(5) matches the fifth item only if it’s a <p> element, p:nth-of-type(5) matches all <p> elements, then finds the fifth <p> element among those.

Let’s start with a slightly different document. It still has 20 items, but some of them are <p> elements and some of them are <div> elements. The <p> elements have rounded corners, as can be seen below.

Using :first-of-type, :last-of-type, and :only-type

With :first-of-type , we can select the first element that matches a selector. How about we give our first <p> element a lime-green background:

p:first-of-type {

background: #cddc39; /* lime green */

}

This will match every <p> element that’s the first <p> element of its parent.

The :Last-of-type pseudo-class works similarly, matching the last such element of its parent.

However, :onLy-of-type will match an element if it’s the only child element of that type of its parent. In the image below, we’re using p:only-of-type to match the only child that’s a paragraph element.

Let’s look at another example of using :first-of-type , but this time with a pseudo-element. Remember the ::first-letter pseudo-element from earlier in this chapter? Well, as you saw, it created an initial capital for every element it was applied to. We’ll now go one step further and limit this initial capital to the first paragraph instead:

p:first-of-type::first-letter {

font: bold italic 3em / .5 serif;

color: #3f51b5;

}

Now our paragraph will have an initial capital, even if it’s preceded by a headline.

Using :nth-of-type() and :nth-last-of-type()

The :nth-of-type() and :nth-Last-of-type() are also functional pseudo-classes. They accept the same arguments as :nth-chiLd() and :nth-Last-chiLd() . But like :first-of- type and :Last-of-type , the indexes resolve to elements of the same type. For example, to select every odd-numbered <p> element, we can use the odd keyword with :nth-of- type() :

p:nth-of-type(odd) {

background: #cddc39;

color: #121212;

}

As you can see from the image below, this only matches odd-numbered paragraph elements, even though there are other element types in between them.

Similarly, using :nth-Last-of-type(even) selects even-numbered <p> elements, but the count begins from the last <p> element in the document—in this case, item 18.

Using *-of-type Pseudo-classes with Non-element Selectors

The “of-type” selectors are designed to be used with element selectors—such as p:first-of-type . You might be tempted to use “of-type” selectors to target the first instance of some other kind of hook, such as a class—as in .item:first-of-type . But this can lead to unexpected results. In the markup that follows, we have three list items and a paragraph element, all of which have a class attribute value of item :

<ul>

<li class=”item”>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>

<li class=”item”>Pellentesque sodales at risus vel fermentum.</li>

<li class=”item”>Fusce et eros iaculis, accumsan ligula ac felis. </li>

</ul>

<p class=”item”>Duis nec ex at arcu rhoncus rhoncus sit amet at est. Donec condimentum accumsan

→justo. Ut convallis faucibus sollicitudin.</p>

Let’s say we want to target just the first element with a class of item . If we add a rule .item:first-of-type {background: magenta;} , you might expect just the first list item to have a magenta background. That isn’t what happens, however, as you can see in the image below.

Instead, our paragraph element also has a magenta background. Because it’s the first paragraph type element in the document, it also matches the .item:first-of-type selector.

The Selectors Level 4 specification adds a new argument syntax for :nth-of-type() / :nth- last-of-type() to bring its behavior more into line with developer expectations: the of [S] syntax, where [S] is a non-element selector.

To use our previous markup example, we could select the first instance of an element with the item class using the following CSS:

:nth-of-type(1 of .item) {

background: magenta;

}

This matches the first element with an item class attribute value. To date, however, Safari is the only browser that supports this syntax.

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

Leave a Reply

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