CSS Structural Pseudo-classes

Structural pseudo-classes select elements by their position among their siblings, with no need for extra classes.

Structural pseudo-classes look at where an element sits inside its parent. They are perfect for styling the first item in a list, alternating table rows, or every third card, all without adding classes to your HTML.

Position pseudo-classes

  • :first-child selects an element that is the first child of its parent
  • :last-child selects the last child of its parent
  • :nth-child(n) selects children by a formula or number
  • :only-child selects an element that is the sole child
  • :nth-of-type(n) counts only elements of the same type

Zebra striping a table

nth-child with even and odd

<!DOCTYPE html>
<html>
<head>
<style>
td {
  padding: 6px 12px;
}

tr:nth-child(even) {
  background: #f2f2f2;
}

tr:nth-child(odd) {
  background: #fff;
}
</style>
</head>
<body>

<table>
  <tr><td>Row 1</td></tr>
  <tr><td>Row 2</td></tr>
  <tr><td>Row 3</td></tr>
  <tr><td>Row 4</td></tr>
</table>

</body>
</html>

Understanding the nth-child formula

nth-child accepts keywords like even and odd, a plain number to target one element, or a formula in the form an+b. For instance, 3n matches every third element, and 3n+1 matches the first, fourth, seventh, and so on.

ArgumentMatches
1Only the first element
oddThe 1st, 3rd, 5th, ...
evenThe 2nd, 4th, 6th, ...
3nEvery third element
3n+1The 1st, 4th, 7th, ...

First and last items

<!DOCTYPE html>
<html>
<head>
<style>
li {
  border-bottom: 1px solid #ddd;
  padding: 4px 0;
}

li:first-child {
  font-weight: bold;
}

li:last-child {
  border-bottom: none;
}
</style>
</head>
<body>

<ul>
  <li>First item</li>
  <li>Middle item</li>
  <li>Last item</li>
</ul>

</body>
</html>
Note: The difference between :nth-child and :nth-of-type is that nth-child counts all siblings, while nth-of-type only counts siblings of the same tag, which matters when a parent holds mixed element types.