How to make a dark theme
Short answer
Declare that the page supports both schemes and set color pairs with light-dark():
<style>
:root { color-scheme: light dark; }
.box { padding: 16px; background: light-dark(white, #1e1e24); color: light-dark(#222, #eee); border: 1px solid light-dark(silver, #444); }
</style>
<div class="box">This box follows your system theme. <button>Button</button></div>The first color is for the light theme, the second for the dark one. The browser picks based on the system setting.
What color-scheme does
color-scheme: light dark also recolors built-in elements: inputs, buttons, scrollbars. Without it a dark page with white inputs looks odd.
With variables and a media query
The classic way is to override variables in a media query:
:root { --bg: white; --text: #222; }
@media (prefers-color-scheme: dark) {
:root { --bg: #1e1e24; --text: #eee; }
}
body { background: var(--bg); color: var(--text); }For an on-site switch add a class on html — say, .dark — with the same variables, and save the choice in localStorage.
Common mistake
People build a dark theme with pure black and pure white — that much contrast tires the eyes quickly. Use a dark gray background and light gray text. And check images and shadows: dark shadows are invisible on a dark background.
Functions used in this recipe
- color-scheme — Tells the browser which color schemes the page supports, so built-in controls and scrollbars match.
- light-dark() — Picks one of two colors depending on the current color scheme.
- @media — Applies rules only under given conditions — the window width, the system theme and others.
- var() — Inserts the value of a custom property (a CSS variable).