How to Create a Dark Mode Toggle for Your Website in 10 Minutes
Dark mode is more than just a trend—it’s a user-preferred feature that reduces eye strain and enhances accessibility. Whether you’re building a portfolio, blog, or web app, adding a dark mode toggle can elevate your site’s user experience. In this quick 10-minute tutorial, we’ll implement a dark mode/light mode toggle using CSS variables and JavaScript, complete with smooth transitions and accessibility best practices. Let’s dive in!
Why Add a Dark Mode Toggle?
Before we start coding, here’s why dark mode matters:
- User Comfort: Reduces glare, especially in low-light environments.
- Accessibility: Supports users with visual sensitivities.
- Modern Appeal: Aligns with current design trends seen in apps like Twitter and Notion.
- Battery Savings: Saves power on OLED screens.
Our goal is to create a toggle that switches between light and dark themes, persists the user’s choice, and ensures a seamless experience.
Prerequisites
- Basic knowledge of HTML, CSS, and JavaScript.
- A code editor (e.g., VS Code).
- A browser with DevTools for testing.
-
Set Up Your HTML
Create a simple HTML file (index.html) with a toggle button and some content to test the theme switch.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Dark Mode Toggle Demo</title> <link rel="stylesheet" href="styles.css"> </head> <body> <header> <h1>Welcome to My Website</h1> <button id="theme-toggle">Toggle Dark Mode</button> </header> <main> <p>This is a sample paragraph to test the dark mode toggle.</p> </main> <script src="script.js"></script> </body> </html>
The button with id="theme-toggle" will trigger the theme switch.
-
Style with CSS Variables
CSS variables (custom properties) make theme switching easy by centralizing color values. Create a styles.css file and define light and dark themes.
/* Default (Light) Theme */ :root { --background-color: #ffffff; --text-color: #333333; --button-bg: #6200ea; --button-text: #ffffff; } /* Dark Theme */ [data-theme="dark"] { --background-color: #1a1a1a; --text-color: #e0e0e0; --button-bg: #bb86fc; --button-text: #000000; } /* Apply Variables */ body { background-color: var(--background-color); color: var(--text-color); font-family: Arial, sans-serif; transition: background-color 0.3s ease, color 0.3s ease; margin: 0; padding: 20px; } header { display: flex; justify-content: space-between; align-items: center; } button { background-color: var(--button-bg); color: var(--button-text); border: none; padding: 10px 20px; cursor: pointer; border-radius: 5px; font-size: 16px; transition: background-color 0.3s ease; } button:hover { opacity: 0.9; } p { max-width: 600px; line-height: 1.6; }
CSS Variables: We define --background-color, --text-color, etc., in :root for the light theme and override them in [data-theme="dark"] for the dark theme.
Smooth Transitions: The transition property ensures color changes are smooth.
Data Attribute: We’ll use data-theme="dark" on the<body>
to toggle themes. -
Add JavaScript for Toggle Functionality
Create a script.js file to handle the toggle logic and persist the user’s theme preference using localStorage.
const toggleButton = document.getElementById('theme-toggle'); const body = document.body; // Check for saved theme in localStorage const savedTheme = localStorage.getItem('theme'); if (savedTheme) { body.setAttribute('data-theme', savedTheme); } // Toggle theme on button click toggleButton.addEventListener('click', () => { const currentTheme = body.getAttribute('data-theme'); const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; // Update theme body.setAttribute('data-theme', newTheme); localStorage.setItem('theme', newTheme); // Update button text for accessibility toggleButton.textContent = newTheme === 'dark' ? 'Toggle Light Mode' : 'Toggle Dark Mode'; });
Theme Persistence: localStorage saves the user’s theme choice, so it persists across page reloads.
Dynamic Button Text: Updates the button label to reflect the next theme, improving accessibility.
Data Attribute Toggle: Switches the data-theme attribute on the<body>
to apply the correct CSS. -
Enhance Accessibility
To make the toggle accessible:
ARIA Attributes: Add aria-label to the button for screen readers.
Keyboard Support: Ensure the button is focusable and works with the Enter key.
Contrast Ratios: Test colors to meet WCAG guidelines (e.g., use tools like WebAIM’s Contrast Checker).Update the HTML button:
<button id="theme-toggle" aria-label="Toggle Dark Mode">Toggle Dark Mode</button>
The JavaScript already updates the button text, which helps screen readers announce the current action.
-
Test Your Dark Mode Toggle
- Open index.html in a browser.
- Click the toggle button to switch between light and dark modes.
- Verify smooth transitions and color changes.
- Refresh the page to ensure the theme persists.
- Use DevTools (F12) to check responsiveness and accessibility.
Bonus Tips
System Preference Support: Detect the user’s system theme with prefers-color-scheme in CSS or JavaScript:
@media (prefers-color-scheme: dark) { :root { --background-color: #1a1a1a; --text-color: #e0e0e0; } }
More Themes: Extend the toggle to support additional themes (e.g., sepia or high-contrast).
Animation Effects: Add subtle animations to elements during theme changes using keyframes.
Conclusion
In just 10 minutes, you’ve built a dark mode toggle that’s functional, accessible, and user-friendly. This feature not only improves your website’s usability but also showcases your skills as a developer. Try experimenting with additional themes or integrating this into your next project!
Have questions or want to share your implementation? Drop a comment below or tweet your demo! Ready to level up? Check out our tutorials on responsive design or JavaScript animations.