In short
Once you have selected an element, you can change it. This lesson shows how to change text, HTML, CSS classes, styles and attributes with JavaScript. textContent vs innerHTML: what is the difference? Every element has a textContent property. It holds the plain text inside the element.
Once you have selected an element, you can change it. This lesson shows how to change text, HTML, CSS classes, styles and attributes with JavaScript.
textContent vs innerHTML: what is the difference?
Every element has a textContent property. It holds the plain text inside the element. If you set it, the old content is replaced with your new text.
The innerHTML property holds the content as an HTML string. If you set it, the browser reads your string as HTML and builds new elements from it.
<!DOCTYPE html>
<html lang="en">
<body>
<p id="greeting">Hello</p>
<p id="notice">Old notice</p>
<script>
const greeting = document.querySelector("#greeting");
const notice = document.querySelector("#notice");
greeting.textContent = "Hi, <b>Sam</b>!";
notice.innerHTML = "Sale ends <strong>today</strong>!";
console.log(greeting.textContent);
console.log(notice.innerHTML);
</script>
</body>
</html>
Hi, <b>Sam</b>!
Sale ends <strong>today</strong>!
On the page, the first paragraph shows the tags as normal characters: Hi, <b>Sam</b>!. The second paragraph shows "today" in bold, because innerHTML turned the string into a real <strong> element.
Why innerHTML with user input is dangerous
Imagine a comment box where a visitor types their name, and you show it with innerHTML. A bad visitor could type an <img> tag with an onerror attribute that runs their own JavaScript. Your page would then run a stranger's code. This attack is called cross-site scripting, or XSS. It can steal data or change what other users see.
Common mistake: Using
innerHTMLto show text that came from a user, a form, a URL or a server. Always usetextContentfor that. It never runs code, because it treats everything as plain text.
Use innerHTML only with HTML that you wrote yourself and fully trust.
How to add, remove and toggle classes with classList
The best way to change how an element looks is usually to add or remove a CSS class. You keep the design in your CSS file and JavaScript only switches the class on or off. Every element has a classList object with helpful methods:
classList.add("name")adds a class.classList.remove("name")removes a class.classList.toggle("name")adds it if missing, removes it if present.classList.contains("name")returnstrueorfalse.
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.card { padding: 16px; border: 1px solid #ccc; }
.highlight { background: #fff6c2; border-color: #e0b800; }
.hidden { display: none; }
</style>
</head>
<body>
<div class="card" id="product">Wireless headphones - $59</div>
<script>
const card = document.querySelector("#product");
card.classList.add("highlight");
console.log(card.classList.contains("highlight"));
card.classList.toggle("hidden");
console.log(card.className);
card.classList.toggle("hidden");
console.log(card.className);
</script>
</body>
</html>
true
card highlight hidden
card highlight
First the card gets a yellow background. Then toggle adds hidden, and the second toggle removes it again, so the card is visible at the end. className shows all the classes as one string. In the Events module you will run toggle when a button is clicked.
The style property vs classes
You can also set CSS directly with the style property. CSS property names with a dash become camelCase: background-color becomes backgroundColor.
const title = document.querySelector("h1");
title.style.color = "darkblue";
title.style.backgroundColor = "#eef";
title.style.fontSize = "2rem";
console.log(title.style.color);
// Output: darkblue
This writes inline styles on the element, as if you had typed a style attribute in the HTML. It is fine for values that JavaScript calculates, like the position of a moving box or the width of a progress bar. For everything else, prefer classes. Classes keep styles in one place, are easier to change, and you can reuse them.
Tip: A good rule: if you could write the style in your CSS file ahead of time, use a class. Use
styleonly for values you can only know while the page is running.
Working with attributes and dataset
Attributes are the extra settings inside a tag, like href, src or alt. You can read them with getAttribute() and change them with setAttribute().
You can also store your own data on an element with data attributes. Any attribute that starts with data- is yours to use. JavaScript reads them through the dataset object. A name like data-product-id becomes dataset.productId (camelCase again).
<!DOCTYPE html>
<html lang="en">
<body>
<a id="docs" href="https://example.com">Read the docs</a>
<img id="photo" src="cat.jpg" alt="A sleeping cat">
<button id="buy" data-product-id="42" data-price="19.99">Buy now</button>
<script>
const link = document.querySelector("#docs");
console.log(link.getAttribute("href"));
link.setAttribute("href", "https://developer.mozilla.org");
link.setAttribute("target", "_blank");
const photo = document.querySelector("#photo");
photo.setAttribute("alt", "A cat sleeping on a sofa");
console.log(photo.getAttribute("alt"));
const button = document.querySelector("#buy");
console.log(button.dataset.productId);
console.log(Number(button.dataset.price) * 2);
button.dataset.inCart = "yes";
</script>
</body>
</html>
https://example.com
A cat sleeping on a sofa
42
39.98
The link now points to MDN and opens in a new tab. The image gets a better description. The button's data values come back as strings, so we use Number() before doing maths. The last line adds a new attribute, data-in-cart="yes", to the button. You can check it in the Elements panel of your browser's developer tools.
Practice exercise
Build a "dark mode" card. Make a <div> with a heading and a paragraph, and a CSS class .dark that sets a dark background and light text. In JavaScript, add the .dark class, log whether the card contains it, and change the heading text to "Dark mode on" with textContent. Then add a data-theme attribute and set it to "dark" using dataset.
Hint: dataset.theme = "dark" creates the attribute data-theme="dark".
Key takeaways
- Use
textContentfor plain text; it is safe with user input. innerHTMLturns a string into HTML; never use it with text from users (XSS risk).classList.add,remove,toggleandcontainsare the cleanest way to change looks.- Use
styleonly for values calculated at runtime; property names are camelCase. getAttributeandsetAttributeread and write attributes;datasetreadsdata-attributes as strings.