HTML Dark Mode
In this page:
Listening to System Preferences
You can detect if a user has enabled dark mode in their device settings by using the prefers-color-scheme media query. This allows your CSS stylesheet to adapt your colors automatically without requiring any JavaScript scripts.
Note: Design your website layouts for dark mode systems automatically using prefers-color-scheme media queries.
Warning: Failing to check system preferences can force a bright white layout on users who prefer comfortable dark themes.
Example: Listening to System Preferences
<style>
@media (prefers-color-scheme: dark) {
body {
background-color: black;
color: white;
}
}
</style>
The color-scheme Meta Tag
The color-scheme meta tag informs the browser that your webpage supports both light and dark themes. This instructs the browser to automatically adjust native elements (like scrollbars, form buttons, and input fields) to match the page theme.
Note: Place the color-scheme meta tag at the very top of your head section to ensure the browser loads it early.
Warning: Failing to declare this meta tag can cause scrollbars to display in bright white on an otherwise dark page.
Example: The color-scheme Meta Tag
<head>
<meta name="color-scheme" content="light dark">
</head>
Dynamic Colors with CSS Variables
Instead of writing duplicate style rules for every element, you can define your page colors using CSS custom properties (variables) inside the root selector. To switch themes, you simply update your variables in one central place.
Note: Use CSS variables to make updating and maintaining your dark mode themes quick and easy.
Warning: Ensure your color variables have high contrast in both themes to keep your content readable.
Example: Dynamic Colors with CSS Variables
<style>
:root {
--bg-color: white;
--text-color: black;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
}
</style>
Toggling Themes with Data Attributes
While system preferences are convenient, users often want a manual toggle button to switch themes. You can handle this by using JavaScript to apply a custom data attribute (like data-theme="dark") to your HTML tag, and styling that attribute inside your CSS.
Note: Save the user's manual theme selection in localStorage so their preference persists across visits.
Warning: Make sure your manual toggle button is accessible to keyboard users who cannot navigate with a mouse.
Example: Toggling Themes with Data Attributes
<html data-theme="dark">
</html>
<style>
[data-theme="dark"] { background-color: black; }
</style>
Preventing Image and Vector Flash
Bright white images and illustrations can look jarring on a dark page. You can use CSS filters to dim your images slightly or invert icons in dark mode to keep them from looking too bright.
Note: Apply a slight opacity filter to your images in dark mode to soften their brightness and blend them into the page.
Warning: Do not invert standard photographic images, as it will distort their colors and make them look like negatives.
Example: Preventing Image and Vector Flash
<style>
[data-theme="dark"] img {
filter: brightness(0.8);
}
</style>
Detecting and Saving Theme Choice with JavaScript
Beyond just following the system preference automatically, most sites let users manually override the theme with a toggle button, then remember that choice using localStorage so it persists across visits, independent of what the operating system is set to.
Note: Check localStorage for a saved preference first, and only fall back to the system's prefers-color-scheme setting if the user has never manually chosen a theme.
Warning: Forgetting to save the user's manual theme choice means it resets back to the system default every time they revisit the site, which feels broken.
Example: Detecting and Saving Theme Choice with JavaScript
<script>
const theme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-theme', theme);
</script>
- Forgetting to include prefers-color-scheme support, forcing a bright white theme on low-light readers.
- omitting the color-scheme meta tag, which leaves scrollbars and inputs displaying in bright white in dark mode.
- Using pure black (#000) and pure white (#fff) values, which can create a harsh, high-contrast display that strains eyes.
- HTML Dark Mode can be detected automatically using the prefers-color-scheme media query.
- The color-scheme meta tag instructs the browser to style scrollbars and native inputs to match the active theme.
- Use CSS variables for easy theme styling, and customize or dim your images using CSS filters to prevent blinding glare.
Standard prefers-color-scheme queries and color-scheme meta tags are natively supported by all modern browsers.
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: