The structural pseudo-classes in CSS are selectors based on the element’s position within its container.
We’ve already seen how to select elements by tag (p), class (.boton), or ID (#cabecera). That’s fine for saying “I want this type of element.”
But many times we need something more precise: the first element of a list, the last link in a menu, the even rows of a table, or every third card in a gallery.
For that, we use structural pseudo-classes. They don’t check if the user is hovering with the mouse, or if a field has focus. They look at where the element is placed within the HTML tree.
First and Last Element
The pseudo-classes
li:first-child {
font-weight: bold;
}
li:last-child {
border-bottom: none;
}
This is very common for removing separators from the last element of a list, highlighting the first result, or adjusting margins without adding extra classes to the HTML.
<ul class="menu">
<li>Home</li>
<li>Services</li>
<li>Contact</li>
</ul>
:first-child doesn’t mean “the first <li> it finds anywhere.” It means “this element is the first child of its parent.”
Selecting by Position with :nth-child()
The pseudo-class
/* Even rows of a table */
tr:nth-child(even) {
background-color: #f5f5f5;
}
/* The third element of a list */
li:nth-child(3) {
font-weight: bold;
}
This allows us to create visual patterns without cluttering the HTML with artificial classes.
<ul>
<li>First element</li>
<li>Second element</li>
<li>Third element</li>
</ul>
:nth-of-type()
The pseudo-class :key[:nth-of-type()] is similar to :nth-child(), but it only counts elements of the same tag type.
<section>
<h2>Title</h2>
<p>First paragraph</p>
<p>Second paragraph</p>
<p>Third paragraph</p>
</section>
/* Selects the second paragraph, ignoring the h2 */
p:nth-of-type(2) {
background: #fef3c7;
}
With p:nth-child(2) we would select the first paragraph, because it’s the second child of section. With p:nth-of-type(2) we select the second <p>. The difference lies in what the browser is counting.
Other Useful Structural Selectors
There are a few more pseudo-classes worth knowing, even if you don’t use them every day.
:only-child: Selects an element if it is the only child of its parent.:first-of-type: Selects the first element of its type.:last-of-type: Selects the last element of its type.:empty: Selects elements that have no content.
.mensaje:empty {
display: none;
}
article p:first-of-type {
font-size: 1.1rem;
}
