How To Tutorial menu

How To Create a Dark Mode Toggle

Learn how to add a button that switches your page between light and dark colours.

Step 1: Colours as CSS Variables

Store your colours in CSS variables on :root. Then define new values for them when the <body> has a dark class.

Example

css
:root {
  --bg: #ffffff;
  --text: #1f2937;
  --card: #f3f4f6;
}
body.dark {
  --bg: #111827;
  --text: #f9fafb;
  --card: #1f2937;
}
body { background: var(--bg); color: var(--text); }
.card { background: var(--card); }

var(--bg) reads the variable. Because every colour uses a variable, one class change recolours the whole page.

Step 2: The Button

Example

html
<button id="themeBtn">Switch to dark mode</button>

Step 3: The JavaScript

The script toggles the dark class, updates the button text, and saves the choice in localStorage so it is remembered next time.

Example

javascript
const btn = document.getElementById("themeBtn");

function applyTheme(isDark) {
  document.body.classList.toggle("dark", isDark);
  btn.innerHTML = isDark ? "Switch to light mode" : "Switch to dark mode";
}

btn.addEventListener("click", function () {
  const isDark = !document.body.classList.contains("dark");
  applyTheme(isDark);
  try { localStorage.setItem("theme", isDark ? "dark" : "light"); } catch (e) {}
});

classList.toggle("dark", isDark) adds the class when isDark is true and removes it when false.

Saving can fail in private browsing windows, so the localStorage lines are wrapped in try ... catch. The page still works, it just will not remember the choice.

The Complete Example

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
  :root { --bg: #ffffff; --text: #1f2937; --card: #f3f4f6; --accent: #059669; }
  body.dark { --bg: #111827; --text: #f9fafb; --card: #1f2937; --accent: #34d399; }
  body { background: var(--bg); color: var(--text); font-family: Arial, sans-serif; padding: 20px; transition: background 0.3s, color 0.3s; }
  .card { background: var(--card); padding: 16px; border-radius: 10px; margin-top: 16px; }
  h1 { color: var(--accent); }
  #themeBtn { background: var(--accent); color: var(--bg); border: none; padding: 10px 16px; border-radius: 6px; font-size: 15px; cursor: pointer; }
</style>
</head>
<body>

<h1>Bilal's Blog</h1>
<button id="themeBtn">Switch to dark mode</button>
<div class="card">
  <h2>Studying at night?</h2>
  <p>Dark mode is easier on the eyes in a dark room.</p>
</div>

<script>
  const btn = document.getElementById("themeBtn");
  function applyTheme(isDark) {
    document.body.classList.toggle("dark", isDark);
    btn.innerHTML = isDark ? "Switch to light mode" : "Switch to dark mode";
  }
  let saved = null;
  try { saved = localStorage.getItem("theme"); } catch (e) {}
  const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
  applyTheme(saved ? saved === "dark" : prefersDark);

  btn.addEventListener("click", function () {
    const isDark = !document.body.classList.contains("dark");
    applyTheme(isDark);
    try { localStorage.setItem("theme", isDark ? "dark" : "light"); } catch (e) {}
  });
</script>

</body>
</html>
Try it Yourself »

Following the System Setting

matchMedia("(prefers-color-scheme: dark)") checks whether the visitor's phone or computer is set to dark mode. The example uses it as the starting theme when nothing has been saved yet.

StepWhat the page does
1Looks for a saved choice in localStorage
2If none, follows the system setting
3On click, switches and saves the new choice

Exercise

Exercise

Why are the colours stored in CSS variables?

Learn How To with a teacher

Join the Web Development course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp