The :nth-child pseudo-class lets you target elements based on their position inside a parent. It is one of the most powerful CSS selectors — once you understand how it works, you can style tables, grids, and lists without adding extra classes to your HTML.

Basic syntax

You pass an argument inside the parentheses that tells the browser which child to select. The argument can be a number, a keyword, or a formula.

/* Select the first list item */
li:nth-child(1) { color: #7c6af7; }

/* Select the third list item */
li:nth-child(3) { font-weight: bold; }

/* Select every even row in a table */
tr:nth-child(even) { background: #1a1d27; }

/* Select every odd row */
tr:nth-child(odd) { background: #0f111a; }

Important: :nth-child counts from 1, not 0. The first child is :nth-child(1), not :nth-child(0).

The an+b formula

The real power of :nth-child is the an+b formula. It selects every ath element starting from position b.

  • a is the cycle size (how often to repeat)
  • n is a counter that starts at 0 and increments by 1
  • b is the starting offset
/* Every 3rd element: 3, 6, 9, 12... */
li:nth-child(3n) { border-bottom: 1px solid #2d3148; }

/* Every 3rd element starting from 1: 1, 4, 7, 10... */
li:nth-child(3n+1) { color: #10b981; }

/* Every 3rd element starting from 2: 2, 5, 8, 11... */
li:nth-child(3n+2) { color: #7c6af7; }

/* First 4 elements only: 1, 2, 3, 4 */
li:nth-child(-n+4) { font-weight: 600; }

Quick reference

ExpressionSelectsExample positions
:nth-child(1)First child only1
:nth-child(odd)All odd children1, 3, 5, 7...
:nth-child(even)All even children2, 4, 6, 8...
:nth-child(2n)Same as even2, 4, 6, 8...
:nth-child(3n)Every 3rd3, 6, 9, 12...
:nth-child(3n+1)Every 3rd from 11, 4, 7, 10...
:nth-child(-n+3)First 3 only1, 2, 3
:nth-child(n+4)From 4th onwards4, 5, 6, 7...

Combining with element types

You can combine :nth-child with a type selector. The element type is checked first, then the position. This is a common source of confusion.

/* Selects a <p> only if it is also the 2nd child of its parent */
p:nth-child(2) { color: #10b981; }

/* This does NOT mean "the 2nd paragraph" */
/* It means: an element that is BOTH a p AND the 2nd child */

Watch out: If the 2nd child is a <span> and not a <p>, then p:nth-child(2) matches nothing — even if there is a <p> nearby.

nth-of-type vs nth-child

Use :nth-of-type when you want to count only elements of a specific type, ignoring siblings of other types.

/* Targets the 2nd <p> regardless of other sibling types */
p:nth-of-type(2) { margin-top: 0; }

/* Alternating colors on <p> elements only, ignoring <h3>, <div> etc */
p:nth-of-type(odd)  { background: #1a1d27; }
p:nth-of-type(even) { background: #0f111a; }

Counting from the end with :nth-last-child

:nth-last-child works exactly like :nth-child but counts backward from the last child instead of forward from the first. Every formula you know from :nth-child applies directly.

/* Select the last item */
li:nth-last-child(1) { color: #7c6af7; }

/* Select the second to last item */
li:nth-last-child(2) { opacity: 0.7; }

/* Select the last 3 items — works regardless of list length */
li:nth-last-child(-n+3) { border-top: 1px solid #2d3148; }

Key use case: :nth-last-child(-n+3) selects the last 3 items in any list regardless of how many total items exist. You do not need to know the list length — this is the clean alternative to adding a class to your last few items via JavaScript.

For more advanced patterns using :nth-last-child — including quantity queries and the CSS Level 4 of S syntax — see the CSS nth-child advanced guide.

Real-world patterns

Zebra-striped table

tbody tr:nth-child(odd)  { background: #1a1d27; }
tbody tr:nth-child(even) { background: #141720; }

Show only the first N items

/* Hide all items after the 5th */
.list-item:nth-child(n+6) { display: none; }

Style last item differently without a class

/* :last-child is cleaner but nth-child works too */
.nav-item:last-child { margin-left: auto; }

/* Or target only middle items (not first or last) */
.nav-item:not(:first-child):not(:last-child) { opacity: 0.8; }

Grid: full-width first item

.grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}

/* Make first card span both columns */
.grid-item:nth-child(1) {
  grid-column: 1 / -1;
}

FAQ

Why is my :nth-child selector not working?

The most common reason is that the element is not at the position you expect. :nth-child counts all siblings inside the parent, including elements of different types. If there is a heading or a div before your list items, the count shifts. Open DevTools, select the parent element, and count all child elements to confirm the actual position number you are targeting.

What is the difference between :nth-child and :nth-of-type?

:nth-child counts all sibling elements regardless of type. :nth-of-type counts only siblings of the same element type. In a list containing only <li> elements they behave identically. In mixed content — for example a section with both headings and paragraphs — they produce different results.

How do I select only the first 3 elements?

Use :nth-child(-n+3). The negative value limits the selection: for n=0 the result is 3, for n=1 it is 2, for n=2 it is 1, and for n=3 it is 0 which matches nothing. So only positions 1, 2, and 3 are selected.

Does :nth-child(0) select anything?

No. :nth-child counts from 1. :nth-child(0) never matches any element. This is a common mistake from developers used to zero-based indexing in JavaScript.

What does :nth-last-child do?

:nth-last-child works exactly like :nth-child but counts backward from the last child. :nth-last-child(1) selects the last element, and :nth-last-child(-n+3) selects the last 3 elements regardless of how many total items exist in the list.

Can I combine :nth-child with :not?

Yes. li:not(:nth-child(-n+3)) selects all list items except the first three. li:not(:first-child):not(:last-child) selects all middle items. These combinations work in all modern browsers.

CSS nth-child Tester — Live Formula Preview

Our nth-child tester lets you write any expression and instantly see which elements are selected — no guessing.

Open :nth-child Tester →