Mastering Dark Mode – Understanding, Detecting and Implementing Dark Mode in the Web Browser
Dark mode is a popular visual theme embraced by operating systems, applications, and websites alike. Whether for aesthetic preference, intended energy savings, or perceived eye comfort, more users are enabling it—raising the question: Is there a scientifically sound benefit to it? Keep on reading and we also show how to best enable a dark mode using JavaScript.
Does Dark Mode Save Energy?
This depends on the display technology:
CRT Displays
Yes. CRTs use phosphorescent pixels activated by an electron beam. A black pixel means no beam—thus, less energy used.
Source
LCD s
It varies. LCDs have always-on backlights and use liquid crystals to block or allow light through. Depending on their default polarisation state, black or white pixels might use more energy. However, the difference in energy usage to switch the crystals polarisation effect is minimal.
Source
OLED Displays
Absolutely. OLEDs are self-emissive—black pixels mean no light emission and therefore no energy used.
Source
As of May 2025, only around 3% of displays in the German market use OLED panels—the rest use LCDs. Source
Is Dark Mode Easier on the Eyes?
The short answer: it feels like it is, but we can’t say for sure.
A study found that while participants felt less fatigue in dark environments with dimmer screens, objective measures of fatigue showed no significant difference. Reference
Can Browsers Automatically Apply Dark Mode?
Technically, a browser could override default CSS styles to implement dark mode. However, no major browser or web standard currently allows an automatic dark mode, to the best of our knowledge.
How to Implement a Dark Mode on Your Website
There are two primary ways to implement dark mode on a website:
Automatic Mode Detection via CSS Media Query
Modern browsers and operating systems allow users to set a preferred color scheme (dark or light). You can automatically adapt your website to this preference using a CSS media query:
@media (prefers-color-scheme: dark) {
body {
background-color: black;
color: white;
}
}
Code-Sprache: CSS (css)
This requires no JavaScript and works immediately based on the user’s OS or browser settings.
User-Controlled Theme Switching via UI
Alternatively, you can give users a visible toggle (like a checkbox or switch) to manually switch between light and dark themes. This approach requires:
- HTML for the toggle
- JavaScript to respond to the toggle
- An identifier (e.g., a class “dark” on ) to indicate the theme to CSS
<body>
<input type="checkbox" id="colortoggle">
<label for="colortoggle">Enable dark mode</label>
</body>
Code-Sprache: HTML, XML (xml)
document.getElementById("colortoggle").addEventListener("click", function () {
document.body.classList.toggle("dark", this.checked);
});
Code-Sprache: JavaScript (javascript)
body.dark {
background-color: black;
color: white;
}
Code-Sprache: CSS (css)
alternatively if text styling in your CSS is not inherited from the body, a quick „1 solution covers almost everything“ case:
body.dark, body.dark * {
background-color: black !important;
color: white !important;
}
Code-Sprache: CSS (css)
Best of Both Worlds: Respect the User, Empower the Choice
Now we know how to detect the browser’s color scheme using CSS, and how to override it using JavaScript, can we improve it?
By default, we can respect the user’s system preference — light or dark — using CSS media queries. At the same time, we provide a manual toggle so users can switch themes themselves – and initialise it appropriately and remember the choice. This hybrid approach gives the best of both worlds: an intelligent default and full control.
Detecting Dark Mode Reliably in the Browser
A Simple CSS Trick
JavaScript doesn’t offer a direct method to read the browser’s active color scheme. However, by combining CSS media queries with a small JavaScript snippet, we can reliably detect whether dark mode is active — and even avoid the dreaded „flash of light mode“ when switching pages.
The Trick: A Zero-Width Div and a Media Query
We add a hidden div that changes size based on the browser’s theme. Here’s the CSS:
#themeChecker {
width: 0px;
pointer-events: none;
}
@media (prefers-color-scheme: dark) {
#themeChecker {
width: 1px;
}
}
Code-Sprache: CSS (css)
When the page loads, this div will have a width of 1px in dark mode and 0px otherwise. This allows JavaScript to determine the current theme by simply checking the width of the element.
HTML and Theme Toggle:
<body>
<div id="themeChecker"></div>
<input type="checkbox" name="colortoggle" id="colortoggle"
onclick="document.cookie='dark=' + this.checked + ';path=/'">
...
</body>
Code-Sprache: HTML, XML (xml)
The checkbox toggles the dark mode manually and stores the user’s choice in a cookie.
JavaScript Detection and Application:
var isDarkMode = document.getElementById("themeChecker")?.clientWidth;
document.cookie.split(";").some(function(c) {
var kv = c.split("=");
if (kv[0].trim() === "dark") {
isDarkMode = kv[1].trim() === "true";
return true;
}
});
document.getElementById("colortoggle").checked = isDarkMode;
Code-Sprache: JavaScript (javascript)
This script:
- Checks if the themeChecker div is 1px wide (meaning dark mode is active) (auto-conversion 1 to true and 0 to false)
- Overrides that with the user’s cookie preference if present
- Updates the checkbox accordingly
If this is placed early enough in the body behind the div and the input and it and the CSS are loaded serially (ie. not “async”), you avoid unwanted flashes of light mode when navigating between pages.
Considerations : Backend Rendering
If you decide to implement this detection server-side (e.g., to pre-render a theme-specific page), do not cache the response globally.
Server-side logic must evaluate each user’s cookie individually — otherwise, everyone might see the first cached user’s mode regardless of their preference.
Bonus: Media Queries Work in SVGs Too!
That’s right — you can also use prefers-color-scheme directly inside SVG files. This is particularly useful for icons or illustrations that need to adapt to the theme context (e.g., white icons for dark mode, and vice versa).
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<style>
rect {fill: black;}
@media (prefers-color-scheme: dark) {
rect {fill: white;}
}
</style>
<rect width="100" height="100" />
</svg>
Code-Sprache: HTML, XML (xml)
This SVG displays a black rectangle by default, but switches to white when the system is in dark mode.
Note:
while media queries like prefers-color-scheme work inside SVGs, you cannot target SVG elements from outside CSS if the SVG is embedded as an img or background-image. For example, CSS like .dark rect {} will have no effect inside an SVG unless the svg is directly placed inside the page as an <svg> HTML element.
A solution then is to load a different SVG file depending on the color scheme media query in CSS.
Bonus: But Watch Out for Favicons!
SVG files with media queries can be used as favicons too, but browsers will only use them if its tag appears before any older .ico favicon links in the HTML <head>.
If you’re unable to change the order of the tags, there’s another option: you can use the media attribute on the <link> to make it apply only in certain situations, like dark mode:
<link rel="icon" media="(prefers-color-scheme: light)" href="favicon.ico">
<link rel="icon" media="(prefers-color-scheme: dark)" href="favicon-dark.ico">
Code-Sprache: HTML, XML (xml)
This article’s phrasing was supported by AI.