Google Chrome 73 has been released, and it adds "dark mode" support to the browser. I notice that a lot of favicons look bad now.
Is there a way to detect if the user is using dark mode and change the favicon?
When the favicon color doesn't work well with dark mode, a common fix is to replace the transparent PNG with a JPG that has a white background, but then you end up with a white square in dark mode. Alternatively, you can use an SVG for the favicon and modify the favicon styling based on the color scheme.
You can click Ctrl + U to view source and look for the favicon in the code ( <link rel="shortcut icon" ).
Adding and removing an icon from the document’s head
works in Firefox but not Safari:
Chrome is still implementing (prefers-color-scheme: dark)
, so the jury’s still out. https://crbug.com/889087. In Chrome 76 with --enable-blink-features=MediaQueryPrefersColorScheme
, this correctly sets the icon when the page is loaded, but does not respond dynamically to changes in dark mode.
Safari adds a grey background to dark icons in dark mode (for example, Wikimedia Foundation, Github), so this workaround isn't necessary for legibility.
Add two link rel=icon
elements with id
s for later:
<link rel="icon" href="a.png" id="light-scheme-icon">
<link rel="icon" href="b.png" id="dark-scheme-icon">
Create a CSS media matcher:
matcher = window.matchMedia('(prefers-color-scheme: dark)');
matcher.addListener(onUpdate);
onUpdate();
Add/remove the elements from the document's head
:
lightSchemeIcon = document.querySelector('link#light-scheme-icon');
darkSchemeIcon = document.querySelector('link#dark-scheme-icon');
function onUpdate() {
if (matcher.matches) {
lightSchemeIcon.remove();
document.head.append(darkSchemeIcon);
} else {
document.head.append(lightSchemeIcon);
darkSchemeIcon.remove();
}
}
CSS has a theme mode detection using prefers-color-scheme
media feature:
@media (prefers-color-scheme: dark) {
...
}
With that in mind, nowadays you can use an SVG as a favicon for your website:
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
Then you can update the SVG favicon design using the CSS prefers-color-scheme
media feature. Below is an SVG rectangle with rounded corners, which has a different color, depending on the active theme:
<svg width="50" height="50" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg">
<style>
rect {
fill: green;
}
@media (prefers-color-scheme: dark) {
rect {
fill: red;
}
}
</style>
<rect width="50" height="50" rx="5"/>
</svg>
Now, considering the current browser support for the SVG favicon, a fallback is required for the older browsers:
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="icon" href="/favicon.png" type="image/png">
<!-- favicon.ico in the root -->
From https://catalin.red/svg-favicon-light-dark-theme/
Here's a demo too: https://codepen.io/catalinred/pen/vYOERwL
To make it a little more generic than Josh's answer, try this whilst the browsers still get around to implementing media
natively. (Notice no hardcoded number of themes, id
s, or media
-queries in the JS; it's all kept in the HTML.)
<link rel="icon" href="/favicon.ico?light" media="(prefers-color-scheme:no-preference)">
<link rel="icon" href="/favicon.ico?dark" media="(prefers-color-scheme:dark)">
<link rel="icon" href="/favicon.ico?light" media="(prefers-color-scheme:light)">
$(document).ready(function() {
if (!window.matchMedia)
return;
var current = $('head > link[rel="icon"][media]');
$.each(current, function(i, icon) {
var match = window.matchMedia(icon.media);
function swap() {
if (match.matches) {
current.remove();
current = $(icon).appendTo('head');
}
}
match.addListener(swap);
swap();
});
});
The upshot is that once that attribute is supported, you just need to remove the Javascript and it'll still work.
I deliberately split /favicon.ico?light
into two tags instead of a single one with media="(prefers-color-scheme: no-preference), (prefers-color-scheme:light)"
because some browsers that don't support media
permanently pick the first rel="icon"
they see… and others pick the last!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With