CSS :nth-of-type() Selector

Beginner
⏱️ 7 min read
📚 Updated: Jul 2026
🎯 4 Examples
Positional

What You’ll Learn

The :nth-of-type() pseudo-class targets elements by their position among siblings of the same tag type. It is the type-aware counterpart to :nth-child().

01

By type

Same tag only.

02

odd / even

Striped rows.

03

2n, 3n+1

Formulas.

04

p:nth-of-type

Paragraph patterns.

05

vs nth-child

Mixed tags.

06

= :first-of-type

Position 1.

Introduction

The :nth-of-type() selector in CSS lets you target elements based on their position among siblings of the same element type. This pseudo-class is extremely flexible, letting you style elements by patterns or specific positions without adding extra classes.

Whether you are working with paragraphs in an article, list items in a menu, or rows in a table, :nth-of-type() is a powerful tool when mixed HTML tags would break a plain :nth-child() count.

Definition and Usage

Write element:nth-of-type(n) where n is a number, the keyword odd or even, or a formula like 2n+1 or 3n+1.

💡
Beginner Tip

Counting starts at 1 among siblings of that type. p:nth-of-type(1) is the first paragraph — even if a <div> appears before the second paragraph. Only <p> elements are counted.

📝 Syntax

The syntax for the :nth-of-type() pseudo-class is:

syntax.css
element:nth-of-type(n) {
  /* CSS properties */
}

element is the tag type you want to match. n can be a number, keyword, or an+b formula.

Common Patterns

ExpressionMatches (5 paragraphs)
p:nth-of-type(2)Second paragraph only
p:nth-of-type(odd)Paragraphs 1, 3, 5
p:nth-of-type(even)Paragraphs 2, 4
li:nth-of-type(2n)Every 2nd list item of its type
p:nth-of-type(3n+1)Paragraphs 1, 4
h2:nth-of-type(-n+2)First two headings of that type

The an+b Formula (By Type)

  • n is a counter starting at 0, increasing by 1 for each sibling of the same type.
  • a is the step size — how often to select (e.g. every 2nd, every 3rd of that type).
  • b is the offset — the starting position in the sequence among that type.
p:nth-of-type(odd) li:nth-of-type(2n) p:nth-of-type(3) p:nth-of-type(3n+1)

Related Selectors

  • :nth-child() — counts all sibling children regardless of tag type
  • :nth-last-of-type() — counts from the end among siblings of the same type
  • :first-of-type / :last-of-type — shorthand for first and last of a type
  • :not() — combine for exclusions like p:not(:nth-of-type(1))

⚡ Quick Reference

QuestionAnswer
Selector typeFunctional structural pseudo-class
Syntaxelement:nth-of-type(n)
Index starts at1 among siblings of that type
CountsOnly siblings of the same tag type
Common useZebra paragraphs, highlight 3rd li, grid by type
Browser supportAll modern browsers

When to Use :nth-of-type()

:nth-of-type() is ideal when tag type and position both matter:

  • Mixed sibling groups — Style every other <p> when headings or divs sit between paragraphs.
  • Highlight a position — Emphasize the third list item with li:nth-of-type(3).
  • Repeating patterns — Every third heading with h2:nth-of-type(3n+1).
  • Article sectionsp:nth-of-type(1) for lead paragraph styling.
  • When nth-child fails — Switch to :nth-of-type() if other tag types shift the count.

👀 Live Preview

Even paragraphs are bold blue; the 3rd paragraph is green. The aside <div> between paragraphs does not affect the count:

First paragraph.

Second paragraph.

Aside note (not a paragraph)

Third paragraph.

Fourth paragraph.

Fifth paragraph.

Examples Gallery

Practice :nth-of-type() with even rows, specific positions, formulas, and mixed sibling layouts.

📜 Core Patterns

Style elements by position among siblings of the same tag type.

Example 1 — Even paragraphs and the third paragraph

Make even paragraphs bold blue with p:nth-of-type(even) and highlight the third with p:nth-of-type(3).

nth-of-type-even.css
p:nth-of-type(even) {
  color: #1d4ed8;
  font-weight: 700;
}

p:nth-of-type(3) {
  color: #15803d;
  font-size: 1.05rem;
}
Try It Yourself

How It Works

even matches the 2nd and 4th paragraphs. The separate :nth-of-type(3) rule highlights the third paragraph with green text regardless of the even styling.

Example 2 — Zebra stripes on odd list items

Use the odd keyword for alternating backgrounds on odd-positioned list items of their type.

nth-of-type-odd.css
li:nth-of-type(odd) {
  background: #f1f5f9;
}

/* Equivalent to :nth-of-type(2n+1) */
Try It Yourself

How It Works

odd is shorthand for every odd-positioned sibling of that type: 1, 3, 5, 7, and so on. It is identical to 2n+1 among <li> elements.

📄 Formulas & Mixed Content

Use an+b expressions and handle layouts where other tags sit between targets.

Example 3 — Every third paragraph starting at 1

The 3n+1 formula selects paragraphs 1, 4, 7, 10, and so on.

nth-of-type-formula.css
p:nth-of-type(3n+1) {
  background: #dcfce7;
  border-left: 4px solid #16a34a;
  padding-left: 0.65rem;
}
Try It Yourself

How It Works

When n=0, the formula gives 1. When n=1, it gives 4. The step a=3 skips two paragraphs of that type between each match.

Example 4 — Second paragraph with a div in between

Show why p:nth-of-type(2) works when p:nth-child(2) would fail.

nth-of-type-mixed.html
<style>
  p:nth-of-type(2) {
    background: #fef3c7;
    border-left: 4px solid #d97706;
    padding-left: 0.65rem;
  }
</style>

<article>
  <p>Opening paragraph.</p>
  <div class="callout">Important callout</div>
  <p>Second paragraph.</p>
  <p>Third paragraph.</p>
</article>
Try It Yourself

How It Works

The callout div is child 2 overall, so p:nth-child(2) would not match any paragraph. p:nth-of-type(2) correctly targets the second <p> among paragraph siblings.

💬 Usage Tips

  • Use odd/even for striping — More readable than 2n+1 for simple zebra patterns by type.
  • Include the element type — Always write p:nth-of-type(), not bare :nth-of-type().
  • Test formulas — Plug n=0,1,2 into an+b to verify which positions match among that type.
  • Mixed layouts — Prefer :nth-of-type() over :nth-child() when other tags appear between targets.
  • Combine with parentsarticle > p:nth-of-type(1) scopes to direct paragraph children.

⚠️ Common Pitfalls

  • Only counts same tag typep:nth-of-type(2) ignores <div> siblings but only matches <p> elements.
  • Confusing with nth-child — A div between paragraphs breaks :nth-child() but not :nth-of-type().
  • 1-based, not 0-based — The first of a type is :nth-of-type(1), not 0.
  • Tag must matchdiv:nth-of-type(1) will not match a <p> element.
  • Overlapping rules — Multiple :nth-of-type() rules can apply to the same element; watch specificity.

♿ Accessibility

  • Contrast on stripes — Alternating row colors must still meet WCAG contrast requirements.
  • Do not rely on color alone — Pair zebra stripes with clear borders or labels where needed.
  • Semantic markup — Use proper <p>, <ul>, and heading tags for screen readers.
  • Reading order unchanged — Positional styling does not affect document order for assistive technology.

🧠 How :nth-of-type() Works

1

Filter by element type

The browser gathers only siblings matching the tag before :nth-of-type().

Type filter
2

Number from the start

Those siblings are indexed starting at 1 from the first element of that type.

Forward index
3

Evaluates n expression

The value inside :nth-of-type() is tested against each type position.

Match
=

Type-aware pattern styling

Stripes, highlights, and grid rhythms work even when mixed sibling tags are present.

🖥 Browser Compatibility

:nth-of-type() is supported in all modern browsers and has been available since CSS3 Selectors.

Baseline · Universal support

Type-based positional selectors everywhere

:nth-of-type() works reliably in Chrome, Firefox, Safari, Edge, and Opera.

99% Universal support
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions
Full support
Opera All modern versions
Full support
:nth-of-type() pseudo-class 99% supported

Bottom line: :nth-of-type() is safe for articles, lists, and mixed-content layouts in all modern projects.

🎉 Conclusion

The CSS :nth-of-type() selector provides a flexible way to style elements based on their position among siblings of the same tag type. It enables dynamic, patterned styling without extra HTML classes.

From simple zebra stripes to complex an+b formulas, mastering :nth-of-type() pairs naturally with :nth-child() and :nth-last-of-type() for complete positional control.

💡 Best Practices

✅ Do

  • Use odd/even for simple zebra striping by type
  • Choose nth-of-type when mixed tags break nth-child
  • Test an+b with n=0,1,2 before deploying
  • Scope with parent selectors like article > p:nth-of-type()
  • Combine with :not() for refined patterns

❌ Don’t

  • Expect it to count across different tag types
  • Use p:nth-child(2) when you mean second paragraph
  • Assume counting starts at 0
  • Omit the element type from the selector
  • Rely on stripe color alone for meaning

Key Takeaways

Knowledge Unlocked

Five things to remember about :nth-of-type()

Use these points when styling by type position.

5
Core concepts
odd 02

Keywords

odd / even.

Syntax
3n+1 03

Formulas

an+b.

Pattern
04

vs nth-child

Mixed tags.

Compare
🌐 05

99% support

All browsers.

Compat

❓ Frequently Asked Questions

The :nth-of-type() pseudo-class matches elements of a specific tag type based on their position among siblings of that same type. You pass a number, odd, even, or an an+b formula inside the parentheses.
:nth-child() counts all sibling children regardless of tag type. :nth-of-type() counts only siblings of the same element type, ignoring other tags in between.
They select the same elements — odd-positioned siblings of that type (1st, 3rd, 5th of that type, and so on). :nth-of-type(even) is equivalent to :nth-of-type(2n).
No. :nth-of-type() only counts p elements. The second paragraph is still p:nth-of-type(2) even if a div sits between the first and second p.
Yes. All modern browsers support :nth-of-type(). It has been available since CSS3 Selectors and works reliably for lists, articles, and tables.

Practice in the Live Editor

Open the HTML editor and experiment with :nth-of-type(), zebra stripes, and mixed sibling layouts.

HTML Editor →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful