jQuery eq vs nth-child Zero-Based Indexing
When manipulating the DOM with jQuery, selecting elements by their
position is a common requirement, typically achieved using either the
:eq() selector or the CSS-standard
:nth-child() pseudo-class. The primary technical difference
between them lies in how they count positions: jQuery's
:eq() relies on a zero-based index targeting an element's
position within a matched set, whereas :nth-child() relies
on a one-based index evaluating an element's position relative to its
sibling elements inside a parent container. Understanding this
distinction prevents common off-by-one errors and unintended DOM
selections.
Zero-Based vs. One-Based Counting
The most direct difference between the two selectors is the starting number of their indexing systems:
:eq(index)(Zero-Based): Borrowing from standard programming arrays and JavaScript conventions, counting starts at0. Therefore,:eq(0)selects the very first element in the matched set,:eq(1)selects the second, and:eq(2)selects the third.:nth-child(n)(One-Based): Borrowing from natural human language and standard CSS specifications, counting starts at1. Therefore,:nth-child(1)targets the first child of a parent,:nth-child(2)targets the second, and:nth-child(0)matches nothing because zero does not represent a valid position in CSS counting.
Collection Indexing vs. Sibling Indexing
Beyond starting at 0 versus 1, these selectors calculate positional context differently across the DOM:
jQuery :eq()
The :eq() selector evaluates the entire matched set
returned by the initial query as a flat array. It does not care about
parent-child relationships or the HTML tree structure.
// Selects the second <li> found on the entire page,
// regardless of which <ul> or <ol> it belongs to.
$("li:eq(1)");If you have two separate lists with three <li>
items each, $("li") matches six elements (indexed
0 through 5). Calling
$("li:eq(3)") returns the first <li> of
the second list because it is the fourth element in the flattened
selection.
CSS :nth-child()
The :nth-child() selector evaluates elements based on
their exact position among siblings sharing the same parent.
// Selects every <li> that is the first child of its respective parent list.
$("li:nth-child(1)");Using the same example of two separate lists,
$("li:nth-child(1)") will match two elements: the first
item of the first list and the first item of the second list, because
both hold position 1 under their respective parents.
Negative Index Support
The two selectors also handle reverse counting differently:
:eq(): Supports negative integers natively in jQuery. Passing a negative number counts backward from the end of the matched set. For instance,$("p:eq(-1)")selects the last paragraph in the selection.:nth-child(): Does not accept negative numbers. To count backward from the end of a parent container using CSS rules, you must use the distinct:nth-last-child()selector, which also uses a 1-based index (e.g.,:nth-last-child(1)selects the final child).
Comparison Summary
| Feature | :eq() |
:nth-child() |
|---|---|---|
| Index Base | Zero-based (0 is the first
element) |
One-based (1 is the first
element) |
| Origin | jQuery-specific selector | CSS3 specification |
| Evaluation Scope | Flat collection of matched elements | Sibling position inside the parent |
| Negative Values | Counts backward from the end
(:eq(-1)) |
Invalid (requires
:nth-last-child()) |
| Performance | Slower (cannot use native
querySelectorAll) |
Faster (delegates to browser CSS engine) |