Skip to main content

How to Get the Closest Parent Element Matching a Selector in JavaScript

When you have a reference to a DOM element, a common task is to traverse up the DOM tree to find a specific parent element. You might need to find the containing <form>, the parent list item <li>, or a wrapper <div> with a certain class. The modern and most effective tool for this is the Element.closest() method.

This guide will teach you how to use closest() to find a parent element by a class, tag name, or any other CSS selector. We will also clarify the difference between finding the closest parent versus the direct parent.

The element.closest(selector) method is the definitive tool for this job. It starts with the element itself, then traverses up through its parents in the DOM tree until it finds the first one that matches the provided CSS selector string.

  • If a match is found, it returns that element.
  • If no match is found (after reaching the top of the document), it returns null.

This method is powerful because it can use any valid CSS selector, making it incredibly flexible.

Finding a Parent by Class

This is the most common use case. You have a child element and need to find its nearest ancestor that has a specific class.

For example, you have a deeply nested element and need to find its parent container with the class .card.

<div class="card">
<div class="card-body">
<p>Some text with a <span id="my-span">span</span> inside.</p>
</div>
</div>

Solution:

const span = document.getElementById('my-span');

// Find the closest ancestor that has the 'card' class.
const cardParent = span.closest('.card');

if (cardParent) {
console.log('Found the card parent element:', cardParent);
} else {
console.log('No parent with that class was found.');
}
// Output: Found the card parent element: <div class="card">...</div>
note

The search begins with the span itself. If the span had the class .card, closest() would have returned the span.

Finding a Parent by Tag Name

You can also use closest() to find the nearest parent of a specific tag type, such as the containing <form> or <li>.

Problem: you have a button inside a list item and need to get a reference to the <li> that contains it.

<ul>
<li>Item 1 <button class="delete-btn">X</button></li>
<li>Item 2 <button class="delete-btn">X</button></li>
</ul>

Solution:

const firstButton = document.querySelector('.delete-btn');

const parentListItem = firstButton.closest('li');

console.log(parentListItem.textContent);
// Output: "Item 1 X"

Distinction: Closest Parent vs. Direct Parent (.parentElement)

It is important to understand the difference between closest() and the .parentElement property.

  • .parentElement: This property returns only the direct parent of an element, one level up. It does not search any further.
  • .closest(selector): This method traverses up the entire DOM tree until it finds a match.

Consider this scenario: HTML:

<div id="grandparent" class="container">
<div id="parent">
<span id="child">Hello</span>
</div>
</div>
const child = document.getElementById('child');

// .parentElement gets only the direct parent.
const directParent = child.parentElement;
console.log(directParent.id); // Output: "parent"

// .closest() can find any ancestor.
const container = child.closest('.container');
console.log(container.id); // Output: "grandparent"

To check if the direct parent has a class: If you only want to check the immediate parent, combine .parentElement with .classList.contains().

const directParentHasClass = child.parentElement?.classList.contains('container');
console.log(directParentHasClass); // Output: false
note

The optional chaining ?. is used to prevent an error if the element has no parent.

Practical Example: Event Delegation in a List

A perfect use case for closest() is handling events on a list of items. By attaching a single listener to the parent <ul>, you can identify which <li> was affected by a click on one of its children.

<ul id="my-list">
<li>Item 1 <button>Delete</button></li>
<li>Item 2 <button>Delete</button></li>
</ul>
const list = document.getElementById('my-list');

list.addEventListener('click', (event) => {
// Check if a button inside the list was clicked
if (event.target.matches('button')) {
// Find the parent <li> of the clicked button
const listItem = event.target.closest('li');
if (listItem) {
console.log('Deleting item:', listItem.textContent);
listItem.remove();
}
}
});

Conclusion

The element.closest(selector) method is the modern, powerful, and recommended way to find parent elements in the DOM.

  • It allows you to find the nearest ancestor that matches any CSS selector, including classes, tag names, and IDs.
  • It is more flexible than .parentElement, which only ever returns the direct parent.
  • It returns the matching element if found, or null if not, making it easy to check for success.

By using closest(), you can write clean, readable, and efficient code for DOM traversal and event handling.