Theme toggle
A tertiary button that names the mode it switches to: "Dark" with a moon in light mode, "Light" with a sun in dark mode. Both labels are in the markup and CSS shows the right one, so it is correct on first paint, before any script runs. The same button is in this site's header from 1024px up, and in the footer below that.
View HTML
<button type="button" class="theme-toggle type-button" data-theme-toggle aria-label="Switch to dark mode">
<span class="theme-toggle__to-dark">
<!-- icon: dark_mode -->
<span>Dark</span>
</span>
<span class="theme-toggle__to-light">
<!-- icon: light_mode -->
<span>Light</span>
</span>
</button>
Theme switch
A segmented Light | Dark control for blue surfaces such as a footer or menu overlay. It is two native radio buttons, so the arrow keys work without a script.
View HTML
<fieldset class="theme-switch" data-theme-switch>
<legend class="visually-hidden">Theme</legend>
<label class="theme-switch__segment">
<input class="visually-hidden" type="radio" name="theme-demo" value="light">
<span class="theme-switch__label type-button">Light</span>
</label>
<label class="theme-switch__segment">
<input class="visually-hidden" type="radio" name="theme-demo" value="dark">
<span class="theme-switch__label type-button">Dark</span>
</label>
</fieldset>
How it works
- A small script in the page head reads a saved choice and sets
data-themeon the<html>element before the page paints, so there is no flash. - With no saved choice, the page follows the browser through
prefers-color-scheme. - Clicking a control saves the choice in
localStorage. Storage can be blocked, so the theme still applies for the visit if it is.
Up next
Stat strip
Up to four large numbers on a light-blue tint.