Find Elements With CSS Selectors
JavaScript DOM Selection
`querySelector` and `querySelectorAll` use CSS syntax to find elements anywhere in the document.
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
// 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); 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.
const nav = document.getElementById("nav"); // no "#" prefix
console.log(nav?.tagName); Scoping the Search
You can call .querySelector(...) on any element, not just
document. The search is limited to that element’s subtree —
fast and predictable.
const card = document.querySelector(".card");
const title = card.querySelector("h2"); // searches inside .card only 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.
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); 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
| Goal | Best call |
|---|---|
| First element matching a CSS rule | document.querySelector("css") |
| All elements matching a CSS rule | document.querySelectorAll("css") |
| Single element by id | document.getElementById("the-id") |
| Inside a specific subtree | el.querySelector("css") |
Up Next
Now that you can find things, time to change them.
JavaScript DOM Manipulation →