Interacting with a webpage using JavaScript starts with one essential task—finding the right elements in the Document Object Model (DOM). The DOM is a structured representation of an HTML document that allows JavaScript to access and manipulate its elements dynamically. One of the most flexible and powerful ways to locate elements is through the querySelector
and querySelectorAll
methods.
These methods accept CSS-style selectors, allowing you to target elements in a way that feels familiar if you’ve used CSS before. Whether you’re selecting elements by tag, class, ID, or a complex combination, these tools offer precise control. This article will show you exactly how to use them—nothing more, nothing less.
Selecting a Single Element with querySelector
The querySelector
method returns the first element that matches a CSS selector string. If multiple elements match, only the first one found is returned.
Take a look at this playful example featuring a couple of wizard names:
<!DOCTYPE html>
<html>
<head>
<title>Wizards List</title>
</head>
<body>
<ul>
<li class="wizard">Albus</li>
<li class="wizard">Sirius</li>
</ul>
<script>
const firstWizard = document.querySelector('.wizard');
firstWizard.style.color = 'blue';
firstWizard.textContent += ' (Headmaster)';
</script>
</body>
</html>
In this example, both list items have the wizard
class, but only the first one, “Albus”, is selected. Its text is updated and colored blue using querySelector('.wizard')
.
Selecting an Element by ID
You can use a CSS ID selector to grab an element with a specific ID by prefixing it with #
. This works exactly like in CSS.
Here’s a spell book being updated:
<!DOCTYPE html>
<html>
<head>
<title>Spellbook</title>
</head>
<body>
<div id="spellbook">Old Spells</div>
<script>
const book = document.querySelector('#spellbook');
book.textContent = 'Updated Spells';
book.style.border = '2px dashed purple';
</script>
</body>
</html>
The element with the ID spellbook
is selected and transformed with new content and a border.
Selecting an Element by Class
The same principle applies when selecting by class. Just use a dot (.
) before the class name.
Here’s a potion changing form:
<!DOCTYPE html>
<html>
<head>
<title>Potion Effect</title>
</head>
<body>
<div class="potion">Invisibility</div>
<div class="potion">Healing</div>
<script>
// Get the first element with the class "potion"
const potion = document.querySelector('.potion');
// Change its background color to light green
potion.style.backgroundColor = 'lightgreen';
// Change the displayed text to "Flying Potion"
potion.textContent = 'Flying Potion';
</script>
</body>
</html>
This script finds the first element with the class potion
, changes its background, and updates its text.
Selecting an Element by Tag Name
You can also use querySelector
to select elements by their tag name. It will return the first one it finds.
Take this sectioned page:
<!DOCTYPE html>
<html>
<head>
<title>Section Focus</title>
</head>
<body>
<section>Introduction</section>
<section>Main Content</section>
<script>
const section = document.querySelector('section');
section.style.fontWeight = 'bold';
section.textContent += ' (First Section)';
</script>
</body>
</html>
Only the first <section>
element gets updated, even though there are two.
Using Descendant Selectors
You can combine selectors just like in CSS to narrow your search. For example, you can select a .card
inside a #library
.
<!DOCTYPE html>
<html>
<head>
<title>Library Cards</title>
</head>
<body>
<div id="library">
<div class="card">Book of Spells</div>
<div class="card">Book of Potions</div>
</div>
<script>
const firstCard = document.querySelector('#library .card');
firstCard.style.background = 'lavender';
firstCard.textContent += ' (Top Pick)';
</script>
</body>
</html>
Even though there are two .card
elements, only the first inside #library
is selected and updated.
Selecting Multiple Elements with querySelectorAll
If you want all matching elements instead of just one, use querySelectorAll
. This returns a NodeList—an array-like structure.
Let’s meet some magical creatures:
<!DOCTYPE html>
<html>
<head>
<title>Creature List</title>
</head>
<body>
<div class="creature">Dragon</div>
<div class="creature">Unicorn</div>
<script>
const creatures = document.querySelectorAll('.creature');
for (let creature of creatures) {
creature.style.color = 'green';
creature.textContent += ' 🐾';
}
</script>
</body>
</html>
Both .creature
elements are selected and looped over to change color and add emojis.
Looping Through Results from querySelectorAll
You can loop through the returned NodeList using for...of
, forEach
, or traditional loops.
Here’s a wizard upgrade party:
<!DOCTYPE html>
<html>
<head>
<title>Wizard Upgrade</title>
</head>
<body>
<div class="wizard">Harry</div>
<div class="wizard">Hermione</div>
<script>
const wizards = document.querySelectorAll('.wizard');
wizards.forEach((wizard) => {
wizard.textContent += ' 🪄';
});
</script>
</body>
</html>
Each .wizard
gets a magical wand emoji with just a few lines of code.
Selecting with Attribute Selectors
CSS lets you select elements based on attributes, and so does querySelector
.
Here’s how you target an input with a name
attribute:
<!DOCTYPE html>
<html>
<head>
<title>Form Input</title>
</head>
<body>
<input type="text" name="email">
<script>
// Select the input element using an attribute selector for name="email"
const emailInput = document.querySelector('input[name="email"]');
// Set a placeholder text to guide the user
emailInput.placeholder = 'Enter your email';
</script>
</body>
</html>
This example uses querySelector
with an attribute selector to precisely grab the input where the name
attribute equals "email"
. Adding a placeholder text helps the user know what to type inside the field, making the form friendlier and clearer.
Using Pseudo-Classes in Selectors
CSS pseudo-classes like :first-child
, :last-child
, or :nth-child
can be used here too.
Let’s target the last message:
<!DOCTYPE html>
<html>
<head>
<title>Messages</title>
</head>
<body>
<ul>
<li class="message">Hello</li>
<li class="message">Goodbye</li>
</ul>
<script>
const lastMsg = document.querySelector('.message:last-child');
lastMsg.style.fontStyle = 'italic';
lastMsg.textContent += ' 👋';
</script>
</body>
</html>
Only the last .message
in the list is touched by the script.
Combining Selectors
You can use commas or chained selectors to target multiple types of elements in one go.
<!DOCTYPE html>
<html>
<head>
<title>Multi Select</title>
</head>
<body>
<div id="main">Main Area</div>
<div class="highlight">Shiny</div>
<article><p>Inside paragraph</p></article>
<script>
const items = document.querySelectorAll('#main, .highlight, article p');
for (let item of items) {
item.style.border = '1px solid black';
}
</script>
</body>
</html>
Each matched element gets a simple black border.
Conclusion
With querySelector
and querySelectorAll
, selecting elements becomes expressive and powerful, thanks to the flexibility of CSS-style selectors. Whether you want the first element or all matches, you can do it easily and clearly. These methods are ideal for anyone who wants to write clean, expressive DOM-manipulating JavaScript.
References
If you’re curious to explore further or want to double-check what you’ve learned, these trusted documentation pages offer more detailed explanations and examples:
- MDN Web Docs: Document.querySelector()
Learn how to use querySelector with real browser examples. - MDN Web Docs: Document.querySelectorAll()
Details on how querySelectorAll works with NodeLists. - W3Schools: JavaScript querySelector
Quick overview and examples to test out selectors.