Skip to main content

How to Get a Child Element by Selector in JavaScript

When you have a reference to a parent DOM element, a very common task is to find a specific child or descendant element within it. You might need to find a child with a certain ID, class, or tag name. The most powerful and flexible tool for this is to scope a query selector to the parent element.

This guide will teach you the modern, standard method for finding descendant elements using querySelector() and querySelectorAll(). You will also learn the important distinction between finding any descendant versus finding only a direct child.

The Core Method: Scoping querySelector and querySelectorAll

The querySelector() and querySelectorAll() methods are not just for the global document object. You can—and should—call them directly on any element object. When you do this, the search is scoped, meaning it will only look for matching elements that are descendants of that parent element.

  • parentElement.querySelector('selector'): Returns the first matching descendant element.
  • parentElement.querySelectorAll('selector'): Returns a NodeList of all matching descendant elements.

Basic Examples: Finding a Child by Class, ID, or Tag Name

This method works with any valid CSS selector, making it a versatile "Swiss Army knife" for DOM queries.

We'll use this structure for our examples.

<div id="parent">
<p class="content-item">Child 1</p>
<span>
<p id="special-child" class="content-item featured">Child 2</p>
</span>
</div>

For example, we have a reference to the #parent div and need to find specific elements inside it.

// Problem: How to find specific children inside this parent?
const parent = document.getElementById('parent');

Solution: by calling querySelector and querySelectorAll on parent, we can easily find what we need.

const parent = document.getElementById('parent');

// --- Find the FIRST child with a class ---
const firstContentItem = parent.querySelector('.content-item');
console.log(firstContentItem.textContent); // Output: "Child 1"

// --- Find ALL children with a class ---
const allContentItems = parent.querySelectorAll('.content-item');
console.log(allContentItems.length); // Output: 2

// --- Find a child by ID ---
// This is very useful for ensuring the ID is within the expected parent.
const specialChild = parent.querySelector('#special-child');
console.log(specialChild.textContent); // Output: "Child 2"

// --- Find all children by tag name ---
const allParagraphs = parent.querySelectorAll('p');
console.log(allParagraphs.length); // Output: 2

Finding Direct Children vs. Any Descendant

By default, a scoped query selector will find matching elements at any level of nesting. If you only want to find direct children (one level deep), you can use the child combinator (>) in your CSS selector.

For example, we need to find a <p> element that is a direct child of #parent, not a more deeply nested one.

<div id="parent">
<p class="direct">Direct Child</p> <!-- This is a direct child -->
<span>
<p class="nested">Nested Child</p> <!-- This is NOT a direct child -->
</span>
</div>

Solution: the space ( ) in a selector is the descendant combinator, while > is the child combinator.

const parent = document.getElementById('parent');

// This finds ALL <p> descendants
const allParagraphs = parent.querySelectorAll('p');
console.log(allParagraphs.length); // Output: 2

// This finds only DIRECT <p> children
const directParagraphs = parent.querySelectorAll(':scope > p');
console.log(directParagraphs.length); // Output: 1
  • :scope: In a scoped query, :scope is a pseudo-class that refers to the element the query is being called on (in this case, parent). So, :scope > p means "find a <p> that is a direct child of parent."

For simple cases, you can also achieve this from the document level:

// This also finds only direct <p> children of #parent
const directParagraphs = document.querySelectorAll('#parent > p');

Conclusion

Finding a child element in JavaScript is a simple and powerful task when you use scoped query selectors.

  • The definitive method is to call parentElement.querySelector('selector') or parentElement.querySelectorAll('selector'). This is the modern best practice.
  • Use any valid CSS selector to find children by ID (#), class (.), tag name (p), or any other attribute.
  • Use the child combinator (>) in your selector (e.g., :scope > .my-class) to find direct children only.

This single, flexible approach is all you need to handle virtually any parent-child query in the DOM.