Dark mode has moved from novelty to expectation. Both iOS and Android support system-level dark mode preferences, and users expect websites to respect them. The implementation is straightforward if your palette is built on CSS custom properties (which PaletteRx exports by default).
Step 1: CSS Variables for Both Modes
:root {
--bg: var(--color-light-base);
--text: var(--color-dark-base);
--surface: #ffffff;
--accent: var(--color-primary);
}
@media (prefers-color-scheme: dark) {
:root {
--bg: var(--color-dark-base);
--text: var(--color-light-base);
--surface: #1e1e2e;
--accent: #818cf8; /* lighter variant */
}
}
Step 2: Manual Toggle
A manual toggle lets users override the system preference. Store the choice in localStorage and apply a data attribute to the html element:
[data-theme="dark"] {
--bg: var(--color-dark-base);
--text: var(--color-light-base);
--surface: #1e1e2e;
--accent: #818cf8;
}
The data attribute takes precedence over the media query when present.
Step 3: Smooth Transitions
Add transitions to background and color changes: transition: background-color 200ms ease, color 50ms ease; Background transitions feel smooth at 200ms. Text color should change nearly instantly (50ms) to avoid readability issues during transition.
Dark Mode Color Adjustments
Do not simply invert all colors. Your primary may need to be lighter in dark mode for adequate contrast against dark backgrounds. Borders become lighter (not darker). Shadows become subtler or disappear. Surface colors need multiple dark levels for depth hierarchy.