JavaScript DOM Selection

Find Elements With CSS Selectors

JavaScript DOM Selection

`querySelector` and `querySelectorAll` use CSS syntax to find elements anywhere in the document.

4 min read Level 2/5 #DOM#querySelector#selectors
What you'll learn
  • Use `querySelector` and `querySelectorAll`
  • Know when to use `getElementById` vs selectors
  • Scope a search to a subtree

document.querySelector("css") returns the first matching element, or null if there is none. document.querySelectorAll("css") returns all matches as a NodeList.

The Two Workhorses

One and many script.js
// returns the first <button class="primary">, or null
const btn = document.querySelector("button.primary");

// returns a NodeList of every matching element
const items = document.querySelectorAll("ul.todo li");
console.log(items.length);
▶ Preview: console

Any CSS selector works — descendants, classes, attribute selectors, :nth-child, :not(), you name it.

document.querySelector("#nav");
document.querySelector("input[type='email']");
document.querySelector("ul > li:first-child");
document.querySelector("a:not([href])");

getElementById Is Still Around

The selector engine handles IDs too (querySelector("#nav")), but getElementById("nav") is slightly faster and reads cleanly when you know exactly what you want.

getElementById script.js
const nav = document.getElementById("nav");  // no "#" prefix
console.log(nav?.tagName);
▶ Preview: console

You can call .querySelector(...) on any element, not just document. The search is limited to that element’s subtree — fast and predictable.

Search inside a card, not the whole page script.js
const card = document.querySelector(".card");
const title = card.querySelector("h2");      // searches inside .card only
▶ Preview: console

NodeList Is Mostly an Array

querySelectorAll returns a NodeList. It has .length and is iterable with for..of, but it’s not a real array — so methods like .map aren’t on it directly.

Iterating a NodeList script.js
const items = document.querySelectorAll("li");

for (const li of items) console.log(li.textContent);

// or spread to a real array if you need array methods
const texts = [...items].map(li => li.textContent);
▶ Preview: console

When Things Aren’t Found

If nothing matches, querySelector returns null and querySelectorAll returns an empty NodeList. Optional chaining saves you from crashes:

document.querySelector(".missing")?.classList.add("on");

Cheat Sheet

GoalBest call
First element matching a CSS ruledocument.querySelector("css")
All elements matching a CSS ruledocument.querySelectorAll("css")
Single element by iddocument.getElementById("the-id")
Inside a specific subtreeel.querySelector("css")

Up Next

Now that you can find things, time to change them.

JavaScript DOM Manipulation →