Switch a whole look on and off with classList.toggle, so CSS does the styling and JavaScript only flips a class.
Dark mode, open menus and highlighted rows are all the same trick: JavaScript adds or removes a class, and CSS does the rest.
You already know CSS: a class such as .dark says how something looks. JavaScript can switch a class on and off:
document.body.classList.toggle("dark");
toggle adds the class if the element has not got it, and removes it if it has. add("dark") and remove("dark") do one or the other. In classList, the class name is written without the dot.
This is the neatest way to change a look: the CSS stays in <style>, and JavaScript only decides when.
The hard part is the dot. In CSS the rule is .dark, but classList.toggle(".dark") makes a class actually called .dark that nothing styles, so nothing happens and there is no error.
Make your prediction first. Help opens once you've locked it in.
<style>
body { font-family: system-ui, sans-serif; padding: 16px; }
.dark { background: midnightblue; color: white; }
.hidden { display: none; }
.big { font-size: 48px; }
</style>
<h1>Night mode</h1>
<p>Click the button to switch between light and dark.</p>
<button id="theme">Switch theme</button>
<script>
const button = document.querySelector("#theme");
button.addEventListener("click", function () {
document.body.classList.toggle("dark");
});
</script>
Where does the dark look come from: the script or the style?
Press Run. One button flips dark on the body; the other flips hidden on the tip. Click each one twice.
<style>
body { font-family: system-ui, sans-serif; padding: 16px; }
.dark { background: midnightblue; color: white; }
.hidden { display: none; }
.big { font-size: 48px; }
</style>
<h1>Night mode</h1>
<button id="theme">Switch theme</button>
<button id="tip-button">Show tip</button>
<p id="tip" class="hidden">Tip: dark pages are easier on the eyes at night.</p>
<script>
document.querySelector("#theme").addEventListener("click", function () {
document.body.classList.toggle("dark");
});
document.querySelector("#tip-button").addEventListener("click", function () {
document.querySelector("#tip").classList.toggle("hidden");
});
</script>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; }
.dark { background: midnightblue; color: white; }
.hidden { display: none; }
.big { font-size: 48px; }
</style>
<h1>Night mode</h1>
<button id="theme">Switch theme</button>
<button id="tip-button">Show tip</button>
<p id="tip" class="hidden">Tip: dark pages are easier on the eyes at night.</p>
<script>
document.querySelector("#theme").addEventListener("click", function () {
document.body.classList.toggle("dark");
});
document.querySelector("#tip-button").addEventListener("click", function () {
document.querySelector("#tip").classList.toggle("hidden");
});
</script>
CSS, add, remove and toggle.
What hides the tip.
Nothing happens, and nothing is wrong... except one dot.
Match each piece with what it does.
Clicking the button does nothing, and there is no red error. Click the line that is wrong.
Reuse a class.
The CSS already has a class called big. Which element should get it?
Give the heading an id, add a button, and toggle big on the heading with classList.

add and remove.
toggle flips; add and remove do one job each.
Make a Light button that removes dark and a Dark button that adds it.

Add a button that toggles the class big on the heading.
This ticks when your page has all of the above.
Replace the one toggle button with a Light button and a Dark button.
This ticks when your page has all of the above.
Write two or more classes of your own in the CSS (an ocean theme, spaced-out letters, a card style, something hidden), and give each its own button. The page on this lesson uses three.
You can now change a whole page with one line. Next: read what someone types.
Students switch CSS classes with classList.toggle, add and remove, hide and show a tip with a hidden class, fix a classList call written with a dot, and make a themed page of their own. About 50 minutes.
Open the teacher guide: answers, solutions, slides and a worksheet.
Read the unit primer first. This ties the CSS lessons to JavaScript: the look is in <style>, the script only flips a class. classList.toggle("dark") on document.body applies a rule to the whole page. The classic slip is classList.toggle(".dark"): no error, no change. The bug task is a logic bug, so students must click the button and notice nothing happens. Hiding with a .hidden { display: none } class is the pattern behind menus, tabs and tips; make the link to "display" from the CSS course.
The dot: the CSS rule is .dark but the class name is dark. The page does nothing and says nothing.
Stretch: Remember the theme with a second class for each choice, or make a button that cycles through three themes using a variable.
Support: Give the CSS classes ready-made and ask students to write only the buttons and listeners.
Next lesson: inputs, reading what someone types.