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.
Fundamentals
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.
Foundation
📝 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
Expression
Matches (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.
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) */
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.
Tips
💬 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 parents — article > p:nth-of-type(1) scopes to direct paragraph children.
Watch Out
⚠️ Common Pitfalls
Only counts same tag type — p: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 match — div: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.
A11y
♿ 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.
Compatibility
🖥 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 ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions
Full support
OperaAll modern versions
Full support
:nth-of-type() pseudo-class99% supported
Bottom line::nth-of-type() is safe for articles, lists, and mixed-content layouts in all modern projects.
Wrap Up
🎉 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.
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
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about :nth-of-type()
Use these points when styling by type position.
5
Core concepts
type01
Same tag only
Counts by type.
Purpose
odd02
Keywords
odd / even.
Syntax
3n+103
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.