Everything you’ve learned so far — variables, functions, loops, conditionals — has lived in the console, invisible to anyone actually looking at the page. Now we wire it up to the real thing. The DOM is the bridge between your JavaScript and the live HTML on the page. Through it, your code can read what’s there, change text and styles, hide and show things, and add or remove elements — all of it live, right in front of the user.
This is the moment JavaScript becomes visible. Every interactive thing you’ve ever seen on a website runs through the DOM. Let’s learn how to use it.
What the DOM is
DOM stands for Document Object Model. When a browser loads your HTML, it builds a live, in-memory version of the page — a tree of all the elements, where every tag becomes an object your JavaScript can reach. That tree is the DOM.
Here’s the key idea: the DOM is your HTML, turned into objects JavaScript can touch. Your <h1>, your buttons, your paragraphs — each one is an object in the DOM that your code can read from and write to. Change an element in the DOM and the page updates instantly to match. You’re not editing the HTML file; you’re reshaping the live page in the browser.
The way in to all of it is a special object called document, which represents the whole page. Everything you do with the DOM starts from document.
Selecting elements
Before you can change an element, you have to find it. The go-to tool is document.querySelector(), which returns the first element matching a CSS selector — the very same selectors you learned in the CSS selectors article:
const title = document.querySelector("h1"); // the first <h1>
const intro = document.querySelector(".intro"); // first element with class "intro"
const menu = document.querySelector("#menu"); // the element with id "menu"
Because it speaks CSS selectors, you already know how to target elements — "h1" for a tag, ".intro" for a class, "#menu" for an id. querySelector hands the element back to you as a DOM object, which you stash in a variable to work with.
To grab every matching element instead of just the first, reach for querySelectorAll, which gives you a list you can loop over:
const allButtons = document.querySelectorAll("button");
allButtons.forEach((btn) => {
console.log(btn);
});
querySelector uses the CSS selectors you already know
You don’t need to learn a new way to find elements — querySelector and querySelectorAll take the exact same selectors as CSS. Tag names, classes (.name), ids (#name), even combinations all work. This is exactly why selectors pay off to learn well: they’re the shared language for targeting elements in both CSS and JavaScript. If you can write a CSS selector for something, you can select it in JavaScript too.
Changing content and styles
Once you have an element in hand, you can read it and change it. Here are the things you’ll reach for most often:
Text content with textContent:
const title = document.querySelector("h1");
title.textContent = "New Heading!"; // changes the visible text
HTML inside an element with innerHTML (use carefully — it interprets tags):
const box = document.querySelector(".box");
box.innerHTML = "<strong>Bold text</strong>";
Styles through the style property:
title.style.color = "teal";
title.style.fontSize = "32px"; // note: camelCase (fontSize, not font-size)
Notice how CSS property names turn into camelCase in JavaScript: font-size becomes fontSize, background-color becomes backgroundColor. The reason is simple — hyphens aren’t allowed in JavaScript property names.
The better way to change styles: classList
Setting styles one at a time with .style works fine, but for anything past a quick tweak there’s a cleaner approach: write the styles in your CSS as a class, then add or remove that class with JavaScript. The classList property is built for exactly this:
const box = document.querySelector(".box");
box.classList.add("active"); // add the "active" class
box.classList.remove("active"); // remove it
box.classList.toggle("active"); // add if absent, remove if present
toggle is the handy one — it’s exactly how a “dark mode” switch or a “show/hide” button works. You write the look once in CSS (.active { ... }), and JavaScript’s whole job is to flip the class on and off. That keeps your styling in CSS where it belongs, and your JavaScript focused on logic.
Prefer classList over inline styles
Reaching for classList.toggle() instead of setting a pile of .style properties keeps a clean split: CSS decides how things look, JavaScript decides when a look gets applied. It’s easier to maintain — all the styling lives in your stylesheet — and flipping one class beats flipping a dozen style properties by hand. As a rule of thumb, change what class an element has, not its individual styles, whenever you can.
Creating and removing elements
The DOM doesn’t stop at changing existing elements — you can build brand-new ones and drop them onto the page. The pattern is three steps: create, configure, attach:
const list = document.querySelector("ul");
const newItem = document.createElement("li"); // 1. create an <li>
newItem.textContent = "A new item"; // 2. set its content
list.appendChild(newItem); // 3. add it to the list
That puts a brand-new <li> on the page, live. This is how dynamic content works — a new message in a chat, a new row in a table, a new product in a list. And you can remove elements just as easily:
const oldItem = document.querySelector(".done");
oldItem.remove(); // removes it from the page
Combine this with the loops and arrays from earlier articles and it gets genuinely powerful: take one array of data and spin a whole list of elements out of it.
Putting it together
Let’s put together something complete and realistic — taking a list of data and rendering it onto the page:
const fruits = ["Apple", "Banana", "Cherry"];
const list = document.querySelector("#fruit-list");
fruits.forEach((fruit) => {
const li = document.createElement("li");
li.textContent = fruit;
list.appendChild(li);
});
This loops through the fruits array, creates an <li> for each one, fills in its text, and appends it to the list on the page. The result: a list that looks like it was built straight from your data. This pattern — data in an array, looped over to build DOM elements — is the foundation of how nearly every dynamic website renders its content. You’ve just tied it all together: arrays, loops, functions, and the DOM, into one real, working feature.
Wrapping up
The DOM is where your JavaScript meets the page, and now you can actually work with it:
- The DOM is your HTML represented as objects JavaScript can read and change; everything starts from the
documentobject. querySelector(first match) andquerySelectorAll(all matches) find elements using the CSS selectors you already know.- Change content with
textContent(orinnerHTMLwhen you need tags), and styles with.style(in camelCase). - Prefer
classList(add,remove,toggle) to switch predefined CSS classes — keeping styling in CSS and logic in JavaScript. createElement+appendChildbuild new elements;.remove()deletes them — the basis of dynamic content.- Looping over data to build DOM elements is the core pattern behind dynamic pages.
You can now read and reshape the page with code. One final piece ties it all to the user: events — responding to clicks, typing, and every other interaction. That’s the last article in this section, and it’s where your pages turn truly interactive, reacting to whatever the user does.