The :odd selector matches elements at odd zero-based indices in the matched set — index 1, 3, 5, and so on. Available since jQuery 1.0; pair with :even; deprecated in jQuery 3.4 in favor of the .odd() method (3.5+).
01
Syntax
tr:odd
02
0-based
1, 3, 5…
03
Official
tr:odd
04
vs :even
0, 2, 4…
05
Second row
Index 1 = odd
06
.odd()
Modern API
Fundamentals
Introduction
Alternating table rows, list highlights, and card grids often need every other element starting from the second item. jQuery’s :odd pseudo-class filters the matched set to elements at odd positions using zero-based indexing.
Official jQuery documentation notes a common surprise: because index 1 is odd, :odd selects the second element, fourth element, sixth element, and so on — not the first, third, fifth as everyday “odd row” numbering might suggest. Index selectors (:eq(), :lt(), :gt(), :even, :odd) always follow another selector that builds the matched set.
Concept
Understanding the :odd Selector
Think of :odd as keeping every other slot starting at index 1:
tr:eq(1), tr:eq(3), tr:eq(5) → same indices as tr:odd.
Four rows indexed 0–3 → :odd matches rows 1 and 3 (second and fourth).
:even matches the complement — indices 0 and 2 (first and third).
Selected elements stay in document order within the filtered set.
💡
Beginner Tip
For new code on jQuery 3.5+, prefer $("tr").odd() over $("tr:odd"). For performance with older patterns, use $("tr").filter(":odd") after a pure CSS selector.
Index filters on the matched set vs child-position CSS.
:odd
tr:odd
Indices 1, 3, 5…
:even
tr:even
Indices 0, 2, 4…
.odd()
$("tr").odd()
Recommended 3.5+
nth-child
tr:nth-child(odd)
CSS per parent
Hands-On
Examples Gallery
Example 1 follows the official jQuery tr:odd demo. Examples 2–5 compare with :even, scope to one table, use the modern .odd() method, and apply the official .filter(":odd") performance pattern.
📚 Official jQuery Demo
Zebra stripe odd-indexed table rows — second, fourth, and so on.
Example 1 — Official Demo: tr:odd
Official jQuery demo — light blue background on rows at index 1, 3, 5…
jQuery
$( "tr:odd" ).css( "background-color", "#bbbbff" );
// Row #1 and #3 highlighted — Row #0 and #2 unchanged
Card 1 and Card 3 → purple border
Separates native query from jQuery extension filter
How It Works
Because :odd is not standard CSS, embedding it in one selector string blocks querySelectorAll for the whole query. Splitting steps helps performance.
Applications
🚀 Common Use Cases
Table zebra striping — tr:odd on rows starting from the second (index 1).
List styling — highlight every other li at odd indices.
Grid layouts — style odd-indexed cards in a flat matched set.
Complement with :even — two-tone UI from one list query.
Legacy maintenance — read existing :odd in older jQuery code.
Migration — replace with .odd() or .filter(":odd").
🧠 How jQuery Evaluates :odd
1
Build matched set
Run the selector before :odd — e.g. all tr or #sales tr.
Query
2
Assign indices
Number elements 0 through length − 1 in document order.
0-based
3
Filter odd indices
Keep elements where index is 1, 3, 5, 7…
Filter
4
✓
Return collection
Multiple elements in document order — ready for .css() or other chaining.
Important
📝 Notes
Available since jQuery 1.0 — 0-based odd indices (1, 3, 5…).
Deprecated in jQuery 3.4 — prefer .odd() (3.5.0+) or .filter(":odd").
Second element always matches when present — index 1 is odd (official docs emphasize this).
Pair with :even for complementary sets — see also official :even selector.
Not valid in native querySelectorAll — jQuery extension only.
Selected elements appear in document order within the filtered result.
Compatibility
Browser Support
The :odd pseudo-class is a jQuery extension — not standard CSS — and works in jQuery 1.0+. It is deprecated in 3.4+; use .odd() (3.5+) instead. The method works in all browsers that support jQuery.
✓ jQuery 1.0+ · deprecated 3.4
jQuery :odd Selector
Works in all jQuery versions. Modern code: $("tr").odd() instead of $("tr:odd").
100%jQuery only
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
:oddUniversal
Bottom line: Learn :odd for legacy zebra striping; write new code with .odd() after a pure CSS selector.
Wrap Up
Conclusion
The :odd selector matches elements at odd zero-based indices in the matched set — the official tr:odd demo stripes the second, fourth, and sixth rows. Remember that index 1 counts as odd, and pair with :even for alternating styles.
For jQuery 3.5+ projects, use .odd() instead of the deprecated pseudo-class. When maintaining legacy code, understand the difference from CSS :nth-child(odd).
Use .filter(":odd") after a CSS selector for performance
❌ Don’t
Assume :odd selects the first row — it starts at index 1
Add new :odd selectors in modern codebases
Confuse with CSS :nth-child(odd) blindly
Use bare $(":odd") without a preceding selector
Expect native querySelectorAll("tr:odd") to work
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about :odd
Odd 0-based indices in the matched set.
5
Core concepts
101
:odd
1, 3, 5…
API
2nd02
Second row
Index 1 counts
Tip
even03
:even
Complement
Pair
.odd04
Modern
3.5+ method
New
demo05
Official
tr:odd
Demo
❓ Frequently Asked Questions
:odd selects elements at odd zero-based indices within the matched set — index 1, 3, 5, and so on. $("tr:odd") matches the second, fourth, and sixth rows among all tr elements in scope. Available since jQuery 1.0.
jQuery uses 0-based indexing. Index 1 is odd, so the second element in the matched set always matches :odd. Official jQuery docs call this counter-intuitive if you expect :odd to mean the first row — use :even for index 0, 2, 4… instead.
:odd matches indices 1, 3, 5… :even matches indices 0, 2, 4… Together they partition the matched set with no overlap. Official docs: see also :even.
Yes — deprecated in jQuery 3.4. Official docs recommend removing :odd from selectors and using the .odd() method (available in jQuery 3.5.0+) on a collection: $("tr").odd() instead of $("tr:odd").
:odd filters the jQuery matched set by 0-based position after your selector runs. CSS :nth-child(odd) counts children within each parent (1-based). A scoped $("table tr:odd") is not the same as tr:nth-child(odd) in every layout.
Official docs: because :odd is a jQuery extension, select with a pure CSS selector first, then filter — e.g. $(".row").filter(":odd") or use .odd() in jQuery 3.5+ so the browser can optimize the initial query.
Did you know?
Official jQuery docs warn that 0-based indexing makes :odd counter-intuitive — it selects the second, fourth, and sixth elements, not the first, third, and fifth. If you want true “every first row in a pair,” use :even instead, or CSS :nth-child(odd) depending on your DOM structure.