Light and dark mode options have become an essential part of modern user experiences. With platforms like YouTube, X, and operating systems such as Windows and macOS setting the standard, users now expect seamless theme adaptability. Offering both modes ensures comfort, accessibility, and personalization, allowing users to engage with content on their terms. This article explores practical strategies for implementing light and dark modes to enhance accessibility, user satisfaction, and design consistency across devices.
Respecting user preferences
A great user experience starts by respecting system preferences. Most operating systems allow users to set their preferred theme globally, and websites should align with these settings by default. However, if a user manually switches themes, storing their preference ensures a consistent experience.
For frequently visited sites like e-commerce platforms or productivity apps, cookies can help persist theme settings across visits, offering a seamless return experience. On the other hand, session storage works best for personal portfolios or one-time visits, maintaining privacy while reducing unnecessary data storage.
// Apply theme based on: 1) User's saved preference, 2) System preference, 3) Light mode default
function applyTheme() {
const savedTheme = // Note: session storage persists data for the session duration only and may not be ideal for frequent visitors.
sessionStorage.getItem('theme');
if (savedTheme) {
document.documentElement.setAttribute('data-view-mode', savedTheme);
} else if (window.matchMedia && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? document.documentElement.setAttribute('data-view-mode', 'dark') : document.documentElement.setAttribute('data-view-mode', 'light'); // Fallback for browsers without matchMedia support) {
document.documentElement.setAttribute('data-view-mode', 'dark');
} else {
document.documentElement.setAttribute('data-view-mode', 'light');
}
}
applyTheme();
Key considerations
When implementing light and dark modes, focus on the following:
- User control and flexibility: Provide an intuitive way for users to toggle between modes manually.
- Accessibility: Ensure adequate color contrast to support readability and usability for all users.
- Brand consistency: Adapt colors carefully without losing brand identity.
- Image and media handling: Use media that adapts to both themes, such as transparent PNGs or CSS filters.
- Performance optimization: Minimize overhead when switching themes to ensure smooth user experience.
- Testing across environments: Test thoroughly on various devices and operating systems to ensure compatibility.
Handling with JavaScript
Empowering users to switch themes manually enhances engagement and control over their experience. A simple and efficient theme toggle mechanism allows users to switch seamlessly between light and dark modes.
// /static/js/modules/themeToggle.js
export function initThemeToggle() {
const themeToggleButton = document.getElementById('theme-toggle-button');
const htmlElement = document.documentElement;
if (!themeToggleButton) {
console.warn('Theme toggle button not found');
return;
}
function toggleTheme() {
const currentMode = htmlElement.getAttribute('data-view-mode');
const newMode = currentMode === 'dark' ? 'light' : 'dark';
htmlElement.setAttribute('data-view-mode', newMode);
sessionStorage.setItem('theme', newMode);
}
themeToggleButton.addEventListener('click', toggleTheme);
// Ensure event listener is removed when component unmounts
window.addEventListener('beforeunload', () => {
themeToggleButton.removeEventListener('click', toggleTheme);
});
}
SCSS implementation
A structured approach ensures consistency and scalability. Aligning the design system with tools like Figma helps maintain uniformity across design and development. The following SCSS example offers a basic approach that can be expanded to fit complex UI needs.
// Define design tokens
$color-light: (
// Core color variables, extend with borders, shadows, etc. for scalability
background: #ffffff,
text: #000000,
primary: #007bff
);
$color-dark: (
background: #121212,
text: #ffffff,
primary: #1e90ff
);
// Mixin to apply themes
@mixin theme-styles($theme) {
background-color: map-get($theme, background);
color: map-get($theme, text);
}
// Applying the themes
[data-view-mode='light'] {
@include theme-styles($color-light);
}
[data-view-mode='dark'] {
@include theme-styles($color-dark);
}
body {
transition: background-color 0.3s ease, color 0.3s ease; // Ensure transitions are optimized for accessibility to avoid discomfort for sensitive users
}
A well-implemented light and dark mode experience enhances user trust and satisfaction. It allows users to interact with your platform in a way that feels natural and intuitive. By focusing on thoughtful implementation, developers can create visually appealing, accessible, and high-performing interfaces that align with user expectations.
Try it yourself
The default theme for this page has been set based on your or system preferences. Feel free to use the theme switch button above to explore and customize your experience.