.closest(selector) (since jQuery 1.3) finds the first element that matches by testing the current element, then walking up through ancestors. Returns a new jQuery set with at most one match per starting element. Does not change the DOM.
Remember
$("li.item-a").closest("ul"); // nearest ul ancestor
$("li.item-a").closest("li"); // matches self first
$("li.item-a").closest("ul", contextEl); // limit search (since 1.4)
$(event.target).closest("li"); // common in click handlers
// closest → start at self, stop at first match (0 or 1)
// parents → start at parent, collect all matches up the tree
Start from a node, pass a selector, get the nearest match upward (or self).
Select a starting element (or use event.target).
Call .closest("selector") — tests self first, then parents.
Stop at the first match; empty set if none.
Optional: pass a context element to bound the search (1.4+).
Chain methods on the result, or check .length.
Piece
Required?
Role
selector / selection / element
Yes
What to match (string, jQuery, or DOM node)
context
No
Since 1.4 — match must be inside this element
Start point
—
Current element first (unlike .parents())
Return value
—
0 or 1 element per start (jQuery object)
Pseudocode
Pseudocode
call $(starts).closest(selector, context?)
result = empty set
for each start in the matched set:
node = start
while node is not null:
if context is set AND node is outside context:
break
if node matches selector:
add node to result
break
node = node.parentElement
return result as a new jQuery object
Reference
Cheat Sheet
Keep these differences next to .parents().
Topic
.closest()
.parents()
Starts at
Current element
Parent element
Stops
First match
Document root (then filter)
Per start
0 or 1
0 or more
Since
1.3 (context 1.4)
1.0
Self match?
Yes
No
Try it
Live Preview
From li.item-a, run .closest() or .parents() and compare results.
I
II
A
B
C
III
closest("li") matches A itself. parents("ul") can return more than one list.
Result
Ready — choose a call and click Run.
Code
jQuery Examples
Short, copy-ready snippets. Open DevTools, or use Try It Yourself for a live editor.
Example 1 — Find the Nearest ul
Official idea: from item A, the first ul upward is ul.level-2.
If that surprises you, you may want .parents() or .parent() instead.
empty
No match → empty set
Check .length before acting — especially with event.target.
context
Context can hide a valid ancestor
A match outside the context element is discarded even if it matches the selector.
one
Only the nearest match
Need every matching ancestor? Use .parents(selector).
removed
Array-return overload is gone
Do not use the old .closest(arrayOfSelectors) API — removed in jQuery 1.8.
Compatibility
Browser Support
.closest() has been part of jQuery since 1.3 (context since 1.4; jQuery/element args since 1.6). It works in every browser that runs your loaded jQuery version.
✓ Stable · jQuery 1.3+
jQuery .closest()
Supported across modern jQuery builds. Prefer a current jQuery 3.x release. Native Element.closest() exists in modern browsers too, but this page covers the jQuery API.
100%With jQuery
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
.closest()Universal
Bottom line: Ideal for event.target → row/card lookups. Remember: tests self first, returns at most one match per start.
Analysis
Performance Notes
Approach
Cost
Best for
.closest(sel)
Cheap
Nearest container / delegation
.parents(sel)
More work
Collecting every matching ancestor
Deep trees, no match
Walks to root
Use a tighter selector or context
.closest() usually stops early. Prefer it over .parents() when you only need the nearest match.
Remember
Key Takeaways
Role: nearest matching ancestor or self — since jQuery 1.3.
Stop: first match only — 0 or 1 per starting element.
vs parents:.parents() skips self and can return many.
Events:$(event.target).closest("…") for row/card clicks.
One line:.closest() walks up from an element (starting with itself) and stops at the first match.
Frequently Asked Questions
.closest() starts at each element in the current set and walks up the DOM tree — testing the element itself first, then parent, grandparent, and so on — until it finds the first match for the selector. It returns a new jQuery object with at most one matched ancestor (or self) per starting element.
.closest() begins with the current element and stops at the first match (zero or one per start). .parents() starts at the parent (not self), collects every ancestor up to the document root, and can return many matches. Use .closest() for the nearest container; use .parents() for all matching ancestors.
Yes. Unlike .parents(), .closest() tests the starting element first. $("li.item-a").closest("li") matches item A itself before looking at any ancestor.
Since jQuery 1.4, .closest(selector, context) limits the upward search so a match must also be a descendant of the context DOM element. The search stops at that boundary.
In a click handler, event.target is often a nested span or icon. $(event.target).closest("li") walks up from the clicked node to the nearest li — even when the click did not land directly on the li.
No. Like other jQuery traversing methods, .closest() only queries the existing DOM and returns a new collection. It does not add, remove, or move elements.