Mini Project: The Dark Mode Switch

Grade 12, page 8 of 9. A two-minute read.

Let's build a theme switcher that remembers your choice, using everything from this grade.

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Theme Switcher</title>
    <style>
      body {
        font-family: sans-serif; max-width: 600px; margin: 40px auto; padding: 0 16px;
        background: #ffffff; color: #22304a; transition: background 0.3s, color 0.3s;
      }
      body.dark { background: #1b2233; color: #f5f5f5; }
      button {
        font-size: 18px; padding: 10px 18px; border-radius: 12px; border: 2px solid currentColor;
        background: transparent; color: inherit; cursor: pointer;
      }
      .note { opacity: 0.7; }
    </style>
  </head>
  <body>
    <h1>🌗 Theme Switcher</h1>
    <p>Click the button, then refresh the page. Your choice is remembered!</p>
    <button id="theme-btn">Switch to dark mode</button>
    <p class="note" id="status"></p>
    <script src="script.js"></script>
  </body>
</html>
script.js
const themeButton = document.querySelector("#theme-btn");
const status = document.querySelector("#status");

function applyTheme(theme) {
  if (theme === "dark") {
    document.body.classList.add("dark");
    themeButton.textContent = "☀️ Switch to light mode";
  } else {
    document.body.classList.remove("dark");
    themeButton.textContent = "🌙 Switch to dark mode";
  }
  status.textContent = `Current theme: ${theme}`;
}

// 1. When the page loads, use the saved theme (or "light" on the first visit)
const savedTheme = localStorage.getItem("theme") || "light";
applyTheme(savedTheme);

// 2. When the button is clicked, flip the theme and save it
themeButton.addEventListener("click", () => {
  const isDark = document.body.classList.contains("dark");
  const newTheme = isDark ? "light" : "dark";
  applyTheme(newTheme);
  localStorage.setItem("theme", newTheme);
});

// 3. Bonus: press "d" on the keyboard to toggle too
document.addEventListener("keydown", (event) => {
  if (event.key === "d") {
    themeButton.click(); // pretend the button was clicked!
  }
});

Click the button, and the page fades smoothly between light and dark. Refresh the page: your choice is still there! Press D on your keyboard: it toggles too. (Calling .click() on an element triggers its click event, as if the user had clicked it.)

Look at how the code is organized: one function (applyTheme) handles showing a theme, and the event listeners just decide which theme to show. Small, focused functions make even interactive code easy to follow.

Try it yourself
  1. Add a third theme, like "burger" (orange background, of course), and cycle through all three on each click.
  2. Add a "Reset" button that removes the saved theme from localStorage and goes back to light mode.
  3. Show how many times the theme has been switched, ever, by saving a counter in localStorage. (Remember: it's stored as a string, so use Number() when you load it!)

You can now build truly interactive web pages: pages that respond to clicks and typing, and that remember things between visits. That's a massive milestone. People get paid real money to do exactly this!

Before we send you off to College, there's one more High School grade. In Grade 13, you'll pick up a collection of modern JavaScript "power-ups": little bits of syntax that make your code shorter, safer and more elegant.

Reading is step one

CurlyScript turns these notes into a game: short questions, an explanation after every answer, and a test at the end of each grade. Free, with nothing to sign up for.

Start learning