Dark Mode Implementation Tips: Add a Toggleable Dark Theme with CSS and JavaScript

Table of Contents
Big thanks to our contributors those make our blogs possible.

Our growing community of contributors bring their unique insights from around the world to power our blog. 

Introduction

Dark mode has gone from a nice-to-have feature to a user expectation. It enhances visual comfort in low-light environments, conserves battery life on OLED screens, and simply looks sleek. If your website or app doesn’t support a toggleable dark mode yet, you could be missing a key opportunity to improve user experience and accessibility.

In this guide, you’ll learn how to implement a toggleable dark mode using CSS and JavaScript, complete with localStorage persistence and system preference detection. Whether you’re updating a portfolio site or a large-scale web app, these best practices will help you add dark mode quickly, cleanly, and confidently.

1. Why Add Dark Mode?

Dark mode isn’t just about aesthetics—it adds real value to your user experience.

Benefits include:

  • Reduces eye strain, especially at night
  • Improves accessibility and visual focus
  • Saves battery on OLED/AMOLED screens
  • Aligns with OS-wide preferences for consistency
  • Boosts user satisfaction and retention

Pro Insight: Apps like YouTube, Twitter, and GitHub have reported increased engagement after introducing dark mode.

2. Use CSS Custom Properties for Theme Flexibility

Rather than rewriting styles for dark mode, use CSS variables to define your color palette. This makes theme switching easy and maintainable.

Example: Base Theme Variables

cssCopyEdit:root {
  --bg-color: #ffffff;
  --text-color: #111111;
  --accent-color: #0077cc;
}

body {
  background-color: var(--bg-color);
  color: var(--text-color);
}

Dark Mode Theme

cssCopyEditbody.dark-mode {
  --bg-color: #121212;
  --text-color: #e4e4e4;
  --accent-color: #4dabf7;
}

This setup allows you to apply the dark-mode class to toggle all styles dynamically.

3. Add a Toggle Switch in HTML

Create a simple dark mode switch in your HTML layout.

htmlCopyEdit<label class="theme-toggle">
  <input type="checkbox" id="darkToggle" />
  Dark Mode
</label>

Style it to suit your design, or replace it with an icon-based toggle (🌞 / 🌙).

4. Enable Theme Switching with JavaScript

Now let’s add JavaScript to switch themes and store the preference.

JavaScript Code:

javascriptCopyEditconst toggle = document.getElementById('darkToggle');
const body = document.body;

// Load saved preference
if (localStorage.getItem('theme') === 'dark') {
  body.classList.add('dark-mode');
  toggle.checked = true;
}

// Toggle event
toggle.addEventListener('change', () => {
  if (toggle.checked) {
    body.classList.add('dark-mode');
    localStorage.setItem('theme', 'dark');
  } else {
    body.classList.remove('dark-mode');
    localStorage.setItem('theme', 'light');
  }
});

Bonus: This ensures your theme stays consistent across page loads using localStorage.

5. Detect System Theme Preferences Automatically

Respect the user’s OS-level preference using the prefers-color-scheme media query.

CSS Detection:

cssCopyEdit@media (prefers-color-scheme: dark) {
  :root {
    --bg-color: #121212;
    --text-color: #e4e4e4;
  }
}

JavaScript Enhancement:

javascriptCopyEditif (!localStorage.getItem('theme')) {
  if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
    body.classList.add('dark-mode');
    toggle.checked = true;
  }
}

6. Style All Components for Both Themes

To provide a complete dark mode experience, style everything:

  • Buttons, links, headers, and footers
  • Forms, inputs, and modals
  • Cards, tables, and navigation menus

Use transition effects to make the change smooth:

cssCopyEditbody {
  transition: background-color 0.3s ease, color 0.3s ease;
}

7. Test for Accessibility and Usability

Checklist:

  • ✅ High contrast ratios for readability
  • ✅ Clear toggle placement
  • ✅ Smooth transition effects
  • ✅ Persistent theme on reload
  • ✅ Compatibility with major browsers

Use tools like Lighthouse, axe DevTools, or Color Contrast Checker to audit your styles.

8. Dark Mode in Frameworks (Bonus Tips)

Using Tailwind CSS? You can enable dark mode via the dark variant:

jsCopyEdit// tailwind.config.js
module.exports = {
  darkMode: 'class', // or 'media'
}

Example:

htmlCopyEdit<div class="bg-white text-black dark:bg-gray-900 dark:text-white">
  Content here...
</div>

Other frameworks like React, Vue, or Next.js can easily integrate this logic via global state or context providers.

Conclusion

Adding a toggleable dark mode is a small enhancement that delivers big results. With just a few lines of CSS and JavaScript, you can create a more accessible, modern, and user-friendly experience that aligns with how people want to use the web today.

At softwarehouse, we help developers and businesses implement accessible design features like dark mode for better engagement and inclusivity.

Ready to give your users more control over their experience? Start with the code above or reach out for custom implementation help.

Let's connect on TikTok

Join our newsletter to stay updated

Sydney Based Software Solutions Professional who is crafting exceptional systems and applications to solve a diverse range of problems for the past 10 years.

Share the Post

Related Posts