With variables, dark mode is mostly: redefine the color variables and keep every other rule unchanged.
Step 1: write the light theme with variables
:root {
--bg: #ffffff;
--text: #1c1b1f;
--card: #f4f0ec;
}
body { background: var(--bg); color: var(--text); }
.card { background: var(--card); }
Step 2: override them in dark mode
Operating systems and browsers expose the visitor’s choice with a media query.
@media (prefers-color-scheme: dark) {
:root {
--bg: #14130f;
--text: #ece8e3;
--card: #232019;
}
}
That is the whole idea. No rule using var(--bg) needs to change.
Try it with a toggle
Here a class on the page stands in for the system setting.
<style>
:root { --bg: #ffffff; --text: #1c1b1f; --card: #f4f0ec; --accent: #d94a00; }
.dark { --bg: #14130f; --text: #ece8e3; --card: #2a261e; --accent: #ff8a50; }
.page { background: var(--bg); color: var(--text); padding: 14px; font-family: system-ui, sans-serif; transition: background .3s, color .3s; }
.card { background: var(--card); padding: 12px; border-radius: 8px; margin-top: 10px; }
.card b { color: var(--accent); }
button { padding: 8px 14px; border-radius: 6px; border: 1px solid var(--accent); background: transparent; color: var(--accent); cursor: pointer; }
</style>
<div class="page" id="page">
<button onclick="document.getElementById('page').classList.toggle('dark')">Toggle theme</button>
<div class="card"><b>Dark mode</b><br>Only the variables changed.</div>
</div>
Press the button. The page restyles itself because only the variables changed. This example uses a little JavaScript. In a real site you would also remember the choice, for example in localStorage.
color-scheme
Tell the browser that your page supports both themes, so it can adjust built-in elements such as scrollbars and form controls:
:root { color-scheme: light dark; }
Dark mode checklist
- Do not use pure black and pure white:
#14130fand#ece8e3are easier on the eyes. - Check contrast in both themes. A brand color that works on white may be too dark on black, so pick a lighter shade for dark mode.
- Images with a white background look odd in dark mode. A mild
filter: brightness(.9)or transparent images help. - Support the visitor’s system setting by default, and add a toggle only if you can remember their choice.