403 words
2 minutes
Dark Mode Implementation Guide
Dark Mode Implementation
Dark mode isn’t just black backgrounds. It’s an art form.
CSS Variables Approach
Base Setup
:root { /* Light mode (default) */ --bg-primary: #ffffff; --bg-secondary: #f5f5f5; --text-primary: #1a1a1a; --text-secondary: #666666; --accent: #3b82f6; --border: #e5e5e5;}
[data-theme="dark"] { --bg-primary: #0a0a0a; --bg-secondary: #171717; --text-primary: #ffffff; --text-secondary: #a3a3a3; --accent: #60a5fa; --border: #262626;}
body { background-color: var(--bg-primary); color: var(--text-primary); transition: background-color 0.3s, color 0.3s;}Usage
.card { background: var(--bg-secondary); border: 1px solid var(--border); color: var(--text-primary);}
.button { background: var(--accent); color: white;}
.muted { color: var(--text-secondary);}JavaScript Toggle
const toggle = document.getElementById('theme-toggle');const html = document.documentElement;
// Check for saved preference or system preferenceconst getTheme = () => { const saved = localStorage.getItem('theme'); if (saved) return saved;
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';};
// Apply themeconst setTheme = (theme) => { html.setAttribute('data-theme', theme); localStorage.setItem('theme', theme);};
// InitializesetTheme(getTheme());
// Toggletoggle.addEventListener('click', () => { const current = html.getAttribute('data-theme'); setTheme(current === 'dark' ? 'light' : 'dark');});React Implementation
import { useState, useEffect, createContext, useContext } from 'react';
const ThemeContext = createContext();
export function ThemeProvider({ children }) { const [theme, setTheme] = useState('light');
useEffect(() => { const saved = localStorage.getItem('theme'); if (saved) { setTheme(saved); } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) { setTheme('dark'); } }, []);
useEffect(() => { document.documentElement.setAttribute('data-theme', theme); localStorage.setItem('theme', theme); }, [theme]);
const toggle = () => setTheme(theme === 'dark' ? 'light' : 'dark');
return ( <ThemeContext.Provider value={{ theme, toggle }}> {children} </ThemeContext.Provider> );}
export const useTheme = () => useContext(ThemeContext);Theme Toggle Button
function ThemeToggle() { const { theme, toggle } = useTheme();
return ( <button onClick={toggle} aria-label="Toggle theme"> {theme === 'dark' ? 'Light' : 'Dark'} </button> );}Tailwind CSS Dark Mode
module.exports = { darkMode: 'class', // or 'media'}<div className="bg-white dark:bg-gray-900"> <p className="text-gray-900 dark:text-white"> Hello, Dark Mode! </p></div>Design Tips
1. Don’t Use Pure Black
/* Too harsh */--bg-dark: #000000;
/* Easier on eyes */--bg-dark: #0a0a0a;--bg-dark: #121212;2. Reduce Contrast
/* Light mode */--text: #000000;
/* Dark mode - slightly muted */--text: #e5e5e5; /* Not pure white */3. Adjust Shadows
.card { box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);}
[data-theme="dark"] .card { box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);}4. Desaturate Colors
:root { --accent: #3b82f6; /* Vibrant blue */}
[data-theme="dark"] { --accent: #60a5fa; /* Lighter, less saturated */}Prevent Flash
<script> (function() { const theme = localStorage.getItem('theme') || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); document.documentElement.setAttribute('data-theme', theme); })();</script>Put this in <head> before CSS loads!
Good dark mode = Happy eyes
Dark Mode Implementation Guide
https://blog.lukkid.dev/posts/dark-mode-guide/