Element.closest() is an instance method that walks up the DOM from an element toward the document root. It returns the first matching ancestor—or the element itself if it matches. Learn CSS selector usage, null when nothing matches, event delegation patterns, and five try-it labs aligned with MDN.
01
Kind
Instance method
02
Walks
Self + ancestors
03
Arg
CSS selector string
04
Returns
Element or null
05
Throws
SyntaxError
06
Status
Baseline widely
Fundamentals
Introduction
When you click a nested icon inside a button, or a span inside a card, you often need the container element—not the tiny node that received the event. Before closest(), developers wrote manual loops with parentElement and matches().
closest(selectors) does that walk in one line. Pass any valid CSS selector; the method tests the current element first, then each parent, until it finds a match or runs out of ancestors.
💡
Beginner tip
Always handle null. If no ancestor matches, closest() returns null—calling methods on the result without a check will throw.
Element.closest() is Baseline Widely available (MDN: across browsers since April 2017). Logos use the shared browser-image-sprite.png sprite from this project.
✓ Baseline Widely available
Element.closest()
Walk up the DOM with one selector string — ideal for event delegation and finding containers.
BaselineWidely available
Google ChromeSupported · Desktop & Mobile
Yes
Microsoft EdgeSupported · Chromium
Yes
Mozilla FirefoxSupported · Desktop & Mobile
Yes
Apple SafariSupported · macOS & iOS
Yes
OperaSupported · Modern versions
Yes
Internet ExplorerNot supported · Use polyfill or parent loop
No
closest()Excellent
Bottom line: Use closest() whenever you need the nearest matching ancestor. Pair with event delegation on parent containers, and always handle null when no ancestor matches.
Wrap Up
Conclusion
Element.closest() is the modern way to find the nearest matching ancestor—or the element itself—using a CSS selector. It returns an Element or null, and it shines in event delegation.
Null-check: const card = el.closest(".card"); if (!card) return;
Use for event delegation on parent containers
Prefer specific selectors (li.menu-item)
Use optional chaining when reading properties: el.closest("form")?.reset()
Combine with data-* attributes for actions
❌ Don’t
Assume a match always exists
Build selectors from unescaped user input
Use matches() alone when you need ancestors
Expect it to search into shadow roots from outside
Replace querySelector for document-wide searches
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about Element.closest()
Walk up the tree with one CSS selector.
5
Core concepts
📝01
Returns
Element | null
API
📄02
Tests
self first
Order
✍️03
Arg
CSS selector
Input
✅04
Baseline
widely available
Status
⚡05
Pattern
delegation
Use case
❓ Frequently Asked Questions
It starts at the element you call it on and walks up through parents toward the document root. It returns the first element (including itself) that matches the CSS selector, or null if none match.
No. MDN marks Element.closest() as Baseline Widely available (across browsers since April 2017). It is not Deprecated, Experimental, or Non-standard.
Yes. The element you call closest() on is tested first. If it matches the selector, that element is returned.
null. Always check the result before using properties or methods on it.
matches() tests only the current element. closest() tests the element and then each ancestor until one matches or the tree ends.
A SyntaxError DOMException is thrown if the selector string is not valid CSS.
Did you know?
closest() tests the element you call it on first. That is why el.closest("div div") can return el itself when it matches—you do not have to reach a parent.