jQuery nth-of-type Selector with Mixed Siblings
This article explains how the jQuery :nth-of-type
selector behaves when applied to a container holding mixed sibling
elements. It outlines the counting algorithm used by the selector,
clarifies the difference between :nth-of-type and
:nth-child, and provides practical examples demonstrating
how jQuery isolates specific HTML tag types regardless of their position
in the DOM tree.
The Core Behavior of
:nth-of-type
When using jQuery’s :nth-of-type() selector, the count
is determined exclusively by the element's tag name (such as
p, div, or span), completely
ignoring any other sibling elements that have different tag names.
Unlike standard position-based selectors, :nth-of-type
creates separate, independent index counters for each unique HTML tag
type under the same parent element.
If you have a container with an assortment of
<h1>, <p>, and
<div> tags, selecting p:nth-of-type(2)
tells jQuery to scan the parent container, filter for only
<p> tags, and select the second
<p> element found, regardless of how many other
non-paragraph tags appear before or between them.
Mixed Siblings Example
Consider the following HTML structure:
<div class="container">
<h1>Title</h1>
<p>First paragraph</p>
<div>First div</div>
<span>A span</span>
<p>Second paragraph</p>
<div>Second div</div>
</div>If you execute the following jQuery code:
$('.container p:nth-of-type(2)').css('color', 'red');jQuery evaluates the siblings as follows:
<h1>Title</h1>— Tag ish1. Skipped.<p>First paragraph</p>— Firstptag encountered (p:nth-of-type(1)).<div>First div</div>— Tag isdiv. Skipped.<span>A span</span>— Tag isspan. Skipped.<p>Second paragraph</p>— Secondptag encountered (p:nth-of-type(2)). Matched.<div>Second div</div>— Tag isdiv. Skipped.
The text "Second paragraph" turns red, even though it is
physically the fifth child inside .container.
Key Differences:
:nth-of-type vs. :nth-child
Understanding this behavior requires distinguishing
:nth-of-type from :nth-child:
:nth-child(n): Counts every single child element under the parent, regardless of tag type. If you queryp:nth-child(2)on the structure above, it checks the second overall child. Since the second child is indeed a<p>, it matches. However,p:nth-child(3)would fail to match anything because the third child is a<div>, not a<p>.:nth-of-type(n): Filters strictly by tag type first. It only increments its counter when encountering the tag specified before the pseudo-class.
Important Caveats with Classes
A common misconception is that :nth-of-type can count by
class name, such as .highlight:nth-of-type(2). In CSS and
jQuery, "type" strictly refers to the HTML tag name, not the class.
If mixed tags share the same class:
<p class="item">Item 1</p>
<div class="item">Item 2</div>
<p class="item">Item 3</p>Running $('.item:nth-of-type(1)') will select both the
first <p> and the first <div>,
because each represents the first element of its respective tag type
that also possesses the .item class. To select elements
strictly by class position regardless of tag type, jQuery's
.eq() method or the :eq() selector should be
used instead.