How to Find the Next or Previous Sibling Element with a Specific Class in JavaScript
When navigating the DOM, a common task is to find the next (or previous) sibling of an element that matches a certain condition, such as having a specific CSS class. While you could manually loop through all siblings, modern JavaScript provides a more direct and readable way to accomplish this.
This guide will teach you how to create a simple, reusable function that can find the next or previous sibling of any element that matches a given CSS selector.
The Core Concepts: nextElementSibling and previousElementSibling
JavaScript's DOM API provides two essential properties for traversing siblings:
element.nextElementSibling: Returns the element immediately following the current one at the same level of the DOM tree, ornullif there isn't one.element.previousElementSibling: Returns the element immediately preceding the current one, ornullif there isn't one.
These properties are the foundation of our solution. They allow us to "walk" along the sibling nodes one by one.
The Solution: A Reusable findSibling Function
Instead of writing separate logic for "next" and "previous," we can create a single, flexible function that handles both. This function will repeatedly step through the siblings until it finds one that matches a given CSS selector.
/**
* Finds the next or previous sibling of an element that matches a selector.
* @param {Element} el - The starting element.
* @param {string} selector - The CSS selector to match.
* @param {string} direction - 'next' or 'previous'.
* @returns {Element|null} The found element or null.
*/
function findSibling(el, selector, direction = 'next') {
let sibling = direction === 'next' ? el.nextElementSibling : el.previousElementSibling;
while (sibling) {
if (sibling.matches(selector)) {
return sibling;
}
sibling = direction === 'next' ? sibling.nextElementSibling : sibling.previousElementSibling;
}
return null;
}
How it works:
- It starts with the very next (or previous) sibling.
- It enters a
whileloop that continues as long as there is asiblingto check. - Inside the loop,
sibling.matches(selector)checks if the current sibling matches our CSS selector (e.g.,.my-class). - If it matches, the function returns that element immediately.
- If not, it moves to the next sibling in the specified direction and repeats.
- If the loop finishes without finding a match, it returns
null.
How to Find the Next Sibling with a Class
Using our reusable function, finding the next sibling with a specific class becomes a simple, one-line call.
For example, you have a starting element and need to find the next sibling that has the class .highlight.
<div>Item 1</div>
<div id="start">Item 2</div>
<div>Item 3 (no class)</div>
<div class="highlight">Item 4 (the target)</div>
<div class="highlight">Item 5</div>
The solution is the following:
// (NOTICE: Include the findSibling helper function from above)
const startElement = document.getElementById('start');
// Find the next sibling that has the 'highlight' class
const nextHighlight = findSibling(startElement, '.highlight', 'next');
if (nextHighlight) {
console.log('Found next highlight:', nextHighlight.textContent);
} else {
console.log('No next highlight found.');
}
Output:
Found next highlight: Item 4 (the target)
How to Find the Previous Sibling with a Class
Similarly, finding a previous sibling is just as easy—you just change the direction argument.
For example, starting from a given element, find the first previous sibling with the class .active.
<div class="item active">Item 1 (the target)</div>
<div class="item">Item 2</div>
<div id="start">Item 3</div>
The solution is the following:
// (NOTICE: Include the findSibling helper function from above)
const startElement = document.getElementById('start');
const previousActive = findSibling(startElement, '.active', 'previous');
if (previousActive) {
console.log('Found previous active item:', previousActive.textContent);
} else {
console.log('No previous active item found.');
}
Output:
Found previous active item: Item 1 (the target)
Practical Example: A Simple "Next Step" Highlighter
This script simulates a multi-step form or tutorial. Clicking a "Next" button finds the current active step, removes its active class, finds the next step, and applies the active class to it.
<div class="step active">Step 1</div>
<div class="step">Step 2</div>
<div class="step">Step 3</div>
<button id="next-btn">Next</button>
// (NOTICE: Include the findSibling helper function from above)
const nextButton = document.getElementById('next-btn');
nextButton.addEventListener('click', () => {
const currentActive = document.querySelector('.step.active');
if (currentActive) {
// Find the next sibling that is also a step
const nextStep = findSibling(currentActive, '.step', 'next');
if (nextStep) {
currentActive.classList.remove('active');
nextStep.classList.add('active');
}
}
});
Conclusion
While JavaScript doesn't have a direct findNextSiblingWithClass() method, you can easily create this functionality by combining basic DOM traversal properties with a simple loop.
- Use
element.nextElementSiblingandelement.previousElementSiblingto step through sibling nodes. - Use
element.matches(selector)to provide a powerful and flexible way to check if an element matches a class, ID, or any other CSS selector. - Encapsulating this logic in a reusable helper function is a best practice that makes your code cleaner and more maintainable.