jQuery .closest() Method

Beginner
6 min read
Updated: Oct 2026
5 examples
Live preview

What Is .closest()?

.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
NeedUse
Nearest match (incl. self)$el.closest(sel)
All matching ancestors.parents(sel)
Direct parent only.parent()
Direct children.children()
Any-depth descendants.find()

How to Use .closest()

Start from a node, pass a selector, get the nearest match upward (or self).

  1. Select a starting element (or use event.target).
  2. Call .closest("selector") — tests self first, then parents.
  3. Stop at the first match; empty set if none.
  4. Optional: pass a context element to bound the search (1.4+).
  5. Chain methods on the result, or check .length.
PieceRequired?Role
selector / selection / elementYesWhat to match (string, jQuery, or DOM node)
contextNoSince 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

Cheat Sheet

Keep these differences next to .parents().

Topic.closest().parents()
Starts atCurrent elementParent element
StopsFirst matchDocument root (then filter)
Per start0 or 10 or more
Since1.3 (context 1.4)1.0
Self match?YesNo

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.

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.

jQuery
$("li.item-a").closest("ul").append(" [closest ul]");
Try It Yourself

How It Works

  1. Start. Begin at li.item-a.
  2. Test self. A is not a ul.
  3. Up. Parent ul.level-2 matches → stop.
  4. Farther. Outer lists are never considered once a match is found.

Example 2 — Match the Element Itself

Official idea: .closest("li") from A selects A — not an ancestor li.

jQuery
$("li.item-a").closest("li").append(" [self]");
Try It Yourself

How It Works

  1. Self first. A is already an li.
  2. Stop. That is the nearest match.
  3. Contrast. .parents("li") would skip self and keep climbing.
  4. Use. Handy when the start node might already be the container.

Example 3 — Limit Search with context

Official idea: match must be a descendant of li#ii.

jQuery
var listItemII = document.getElementById("ii");
$("li.item-a").closest("ul", listItemII).append(" [in II]");
var outer = $("li.item-a").closest("#one", listItemII).length;
$("#log").text("#one with context II → length " + outer);
Try It Yourself

How It Works

  1. Context. listItemII is the boundary element.
  2. Inside. ul.level-2 is under #ii → allowed.
  3. Outside. #one is not a descendant of #ii → empty.
  4. Since. Context argument arrived in jQuery 1.4.

Example 4 — Event Delegation with .closest()

Official Ex. 1 idea: click a nested span/strong — still find the nearest li.

jQuery
$(document).on("click", function (event) {
  var $li = $(event.target).closest("li");
  if (!$li.length) return;
  if ($li.attr("data-on") === "1") {
    $li.find("[data-mark]").remove();
    $li.removeAttr("data-on");
  } else {
    $li.append(" [on]");
    $li.attr("data-on", "1");
  }
});
Try It Yourself

How It Works

  1. Target. Click may land on span or strong.
  2. Climb. .closest("li") finds the wrapping list item.
  3. Toggle. Mark / unmark that li.
  4. Pattern. Classic “clicked inside a row/card” handling.

Example 5 — .closest() vs .parents()

Same start node — compare how many ancestors each returns.

jQuery
var start = $("li.item-a");
$("#out").text(
  "closest ul: " + start.closest("ul").length + "\n" +
  "parents ul: " + start.parents("ul").length + "\n" +
  "closest li text: " + start.closest("li").contents().first().text().trim() + "\n" +
  "parents li count: " + start.parents("li").length
);
Try It Yourself

How It Works

  1. closest ul. Stops at the nearest list (count 1).
  2. parents ul. Collects every ul ancestor (count 2).
  3. closest li. Matches A itself.
  4. parents li. Skips self; keeps outer ancestor items only.

Edge Cases & Pitfalls

These mix-ups show up most in event handlers.

self

Self can match — unlike .parents()

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.

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 Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All 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.

Performance Notes

ApproachCostBest for
.closest(sel)CheapNearest container / delegation
.parents(sel)More workCollecting every matching ancestor
Deep trees, no matchWalks to rootUse a tighter selector or context

.closest() usually stops early. Prefer it over .parents() when you only need the nearest match.

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.

Next: .contents() Method

Get children including text and comment nodes — not just elements.

.contents() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

10 people found this page helpful