The .parents() traversing method climbs the DOM tree — it returns every ancestor of each matched element, optionally filtered by a selector. This tutorial covers the official nested-list and parent-tag demos, comparisons with .parent(), .closest(), and practical click-to-highlight patterns.
01
All up
Every ancestor
02
Selector
.parents(".x")
03
vs .parent()
All vs one
04
vs .closest()
Many vs first
05
Order
Near → far
06
Since 1.0
Core API
Fundamentals
Introduction
Sometimes one parent is not enough. You need every wrapper above an element — the ul, the containing li, the outer list, body, and html. That is what .parents() is for.
Available since jQuery 1.0, .parents([selector]) walks up from each matched element’s immediate parent toward the root, building a new jQuery object of ancestors. Unlike .parent(), it does not stop after one level. Unlike .closest(), it can return many ancestors and never includes the starting element itself.
Concept
Understanding the .parents() Method
Given a jQuery object representing DOM elements, .parents() follows parentNode links upward until there are no more element ancestors. When you pass a selector, only ancestors that match are kept — but jQuery still walks the full chain internally to find them.
Results for a single element are ordered from the closest ancestor outward. When several elements start the search, jQuery merges their ancestor sets in reverse order of the original elements and removes duplicates — handy when batch-processing, but worth remembering when debugging order.
💡
Beginner Tip
$("li.item-a").parents() returns the inner ul, the wrapping li, the outer ul, body, and html — every ancestor of item A. .parent() would stop at the first ul only.
Foundation
📝 Syntax
General form of .parents:
jQuery
.parents( [ selector ] )
Parameters
selector (optional) — a string containing a selector expression. Only ancestors that match are included in the result.
Return value
A new jQuery object containing all ancestors of each element in the current set (filtered when a selector is provided). Does not include the starting elements.
Official jQuery API nested list example
jQuery
$( "li.item-a" ).parents().css( "background-color", "red" );
// Red on inner ul, li II, outer ul, body, html — all ancestors
Cheat Sheet
⚡ Quick Reference
Goal
Code
All ancestors
$("span").parents()
Only div ancestors
$("span").parents("div")
All ul ancestors in nested list
$("li.item-a").parents("ul")
Immediate parent only
$("li").parent()
Nearest matching ancestor (incl. self)
$("span").closest(".card")
List ancestor tag names
$("b").parents().map(fn).get().join(", ")
Compare
📋 .parents() vs .parent() vs .closest() vs .parentsUntil()
Four upward methods — all ancestors, one level, first match, or stop before a boundary.
.parents()
all up
Every ancestor — optional filter
.parent()
+1 up
Immediate parent only
.closest()
first match
Self + ancestors until selector hits
.parentsUntil()
up to stop
Ancestors until boundary — not incl.
Hands-On
Examples Gallery
Examples 1–3 follow the official jQuery API documentation. Use DevTools or the Try-it links to run each snippet in the browser.
📚 Getting Started
Official jQuery demos for full ancestor traversal.
Example 1 — Official Demo: Style All Ancestors of Item “A”
From nested item A, highlight every ancestor up to html.
Each b shows: "My parents are: P, DIV, BODY, HTML"
Comma-separated ancestor tag names from .parents().map()
How It Works
The official demo chains .parents() with .map() and .get() to flatten ancestor tag names into a readable string — a classic learning exercise for the DOM tree.
Example 3 — Official Demo: Unique div Parents of Selected Spans
Click spans to toggle selection, then outline every unique div ancestor.
jQuery
function showParents() {
$( "div" ).css( "border-color", "white" );
var len = $( "span.selected" )
.parents( "div" )
.css( "border", "2px red solid" )
.length;
$( "b" ).text( "Unique div parents: " + len );
}
$( "span" ).on( "click", function() {
$( this ).toggleClass( "selected" );
showParents();
});
Selected spans → red border on every div ancestor
Counter shows unique div count in the merged jQuery set
How It Works
.parents("div") filters ancestors to div elements only — skipping body and html. Multiple selected spans can share ancestors; jQuery deduplicates in the combined result.
📈 Practical Patterns
Contrast depth with .parent(), then filter to specific ancestor types.
Example 4 — .parent() vs .parents()
One level up vs every ancestor from the same starting element.
.parent() → red outline on inner ul only
.parents() → blue outline on every ancestor chain element
How It Works
Side-by-side demos make the one-level vs full-chain difference obvious. Reach for .parent() when the direct wrapper is enough; use .parents() when context from higher levels matters.
Example 5 — Filter Ancestors With .parents("ul")
From a deep list item, collect every ul ancestor — inner and outer lists.
Inner ul and outer ul → .ancestor-list class
li, body, html → skipped by the "ul" filter
How It Works
The selector argument is the most common real-world pattern — you rarely need every ancestor, but you often need all matching containers of a type, such as every ul or div.panel above a node.
Applications
🚀 Common Use Cases
Highlight ancestor chain — official pattern: $("li.item-a").parents().css("background-color", "red").
Find all container divs — $("span.selected").parents("div") for layout debugging.
Breadcrumb context — .parents("li").map(...) to build a path from nested menu items.
Form validation styling — $("input:invalid").parents(".form-row").addClass("error") when wrappers nest.
Table row actions — $("td").parents("tr") when the click target is not the row itself.
Inspect DOM hierarchy — official b demo: list ancestor tag names with .map().
🧠 How .parents() Climbs the DOM Tree
1
Start with source elements
jQuery object holds one or more DOM nodes.
Input
2
Walk parentNode links
Climb from immediate parent up to html.
Traverse
3
Apply selector filter
If provided, keep only matching ancestors.
Filter
4
↑↑
Return & chain
New jQuery object — ancestors ordered near to far, duplicates removed.
Important
📝 Notes
Available since jQuery 1.0 — optional selector filters which ancestors are returned.
Does not include the starting element — only ancestors above it (unlike .closest()).
Travels all the way up — not limited to one level like .parent().
$("html").parents() returns an empty set; $("html").parent() returns document.
With multiple starting elements, result order reverses the original set and deduplicates.
Pushes onto jQuery’s internal stack — pair with .end() to restore the previous set.
Compatibility
Browser Support
.parents() has been part of jQuery since 1.0+. It relies on standard parent-node traversal with no browser-specific behavior beyond jQuery itself.
✓ jQuery 1.0+
jQuery .parents()
Supported in jQuery 1.x, 2.x, and 3.x across all modern browsers and IE with supported jQuery builds. Combines ancestor walking with jQuery selector filtering and collection semantics.
100%With jQuery loaded
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
.parents()Universal
Bottom line: Safe in any jQuery project. Use .parents() for the full ancestor chain; use .parent() for one step or .closest() for the nearest match.
Wrap Up
Conclusion
The jQuery .parents() method returns every ancestor of each element in the current collection — walking up from the immediate parent toward html. It is the full-chain counterpart to .parent(), which stops after one level.
Remember the official list lesson: from item A, the inner ul, wrapping li, outer ul, body, and html all turn red. Use .parents(selector) to filter ancestors, .closest() when you need only the nearest match, and .parent() when the direct parent alone is enough.
Use .parents(selector) to filter ancestors by type or class
Pair with .first() when you want the nearest matching ancestor without .closest()
Use .parents() when you need several ancestor levels at once
Chain .map() and .get() to extract data from ancestor sets
Call .end() after .parents() when continuing on the original set
❌ Don’t
Use .parents() when only the direct parent matters — use .parent()
Expect .parents() to include the starting element — use .closest()
Assume order is arbitrary — ancestors are near-to-far for a single element
Walk ancestors manually in a loop when .parents() already solves it
Confuse .parents() with .parentsUntil() — the latter stops at a boundary
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about .parents()
Climb the full ancestor chain.
5
Core concepts
↑↑01
.parents()
All up
API
↑02
.parent()
One level
Compare
1st03
.closest()
First match
Compare
?04
Selector
Filter type
Filter
html05
Edge
empty set
Note
❓ Frequently Asked Questions
.parents() returns every ancestor of each element in the current jQuery collection — walking up the DOM tree from the immediate parent toward the document root. An optional selector keeps only ancestors that match.
.parent() moves up exactly one level — the direct parent only. .parents() keeps climbing and collects every ancestor (optionally filtered). From a nested li, .parent() gives one ul; .parents('ul') can return multiple ul ancestors at different depths.
.parents() returns all matching ancestors (or every ancestor when no selector is passed). .closest(selector) stops at the first match and includes the starting element itself. Use .closest() when you need one nearest match; use .parents() when you need the full ancestor chain or several levels.
For a single starting element, ancestors are ordered from the closest parent outward — parent first, then grandparent, and so on up to html. When multiple starting elements are in the set, jQuery reverses the original element order and removes duplicates in the combined result.
When you call .parents(selector), only ancestors that match are included. If none match, you get an empty jQuery object — safe to chain. Use .closest(selector) when you want the first match even if it is several levels up.
An empty jQuery object — html has no element ancestors. By contrast, $('html').parent() returns the document node. This edge case shows .parents() collects element ancestors only, not document.
Did you know?
When multiple elements call .parents(), jQuery reverses the order of the original matched set when building the combined ancestor list and removes duplicates. That is why the official span-click demo reports a unique div count — shared ancestors appear once even when several spans select them.