Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How make a page's icon responsive to the user's color scheme preference?

Tags:

html

favicon

Pages offer icons for the browser either via favicon.ico or via various <link> tags like

<link rel='icon' type='image/png' href='icon.png'>

The problem is if the icon is the same color as the browser's tabs then you can't see it.

chrome with custom theme

safari

firefox

There are some semi-obvious solutions

(1) as a user, pick theme whose tabs are not pure white or pure black (and pray the sites don't choose the same color)

(2) as a developer, pick an icon color that's not pure white or pure black (and pray it doesn't match the user's theme) or add a frame to the icon.

But, just curious, as a developer, is there a way to tell the browser to use one icon if the tab is dark and a different icon if the tab is light? SVG CSS for example? Different <link> tags?

PS: Yes, I get that the theme above is gaudy. It's "green for google" vs other profiles I use to separate accounts. That way it's easy for me to know which account each browser window is using. I have 7+ profiles, each with a different and very distinct theme 😉

like image 462
gman Avatar asked Nov 07 '22 00:11

gman


1 Answers

You're talking about two possible things:

  1. Browser theme
  2. OS color scheme

Your screenshot depicts the first. Chrome does not expose a user's chosen theme to its Javascript APIs. Nor does any other browser to my knowledge. That's probably a good thing: it would be extremely unique – therefore a way to fingerprint users.

But the second, OS color scheme, is exposed to browsers! This is usually only either one of dark or light. Not every operating system supports color schemes, but the ones that do typically use terms like "Dark Mode" when they talk about it. Apple has some documentation on how to use Dark Mode on macOS, for example.

If an OS supports color schemes, they're exposed to the browser through CSS media queries: @media ( prefers-color-scheme: dark ). It's a feature with >91% global browser support.

The nice thing about it being in CSS is that you can thus serve an SVG for your favico that has that media query in it, and your users will automatically get the right one.

Thomas Steiner popularized this technique in this 2019 post. An example of that:

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <style>
    path {
      fill: black;
    }

    @media (prefers-color-scheme: dark) {
      path {
        fill: white;
      }
    }
  </style>
  <path d="....." />
</svg>

Back to your post, though: a user could potentially have a dark color scheme, and a (say) gaudy green browser theme, so the favico would possibly look bad either way. No avoiding it.

The easiest solution, then?

Put a background color on your favico. A solution as old as time!

like image 54
Leland Avatar answered Nov 15 '22 11:11

Leland