Is it possible to use a different favicon for browsers that support theme-color?
Asked Answered
P

2

17

Is there a way to set a different favicon for browsers that support theme-color, either via the meta tag or manifest.json? I have a jet black theme bar, but a mostly-black favicon for use on desktop browsers. I'd like to have an alternate white favicon for mobile browsers, but I don't want to make the assumption that mobile browser === theme-color support, as that's not always going to be the case.

Desktop favicon example:

Desktop favicon

Mobile favicon example: Mobile favicon

Pregnancy answered 20/4, 2018 at 10:13 Comment(0)
P
13

The browser's theme is accessible through the prefers-color-scheme media query. Unfortunately, as the favicon is not a page element, you cannot use the media query in a CSS file to, say, switch between two images.

The solution is to combine prefers-color-scheme with SVG, which can embed CSS. Declare an SVG favicon:

<link rel="icon" href="my_icon.svg">

And use the media query in the SVG itself:

<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
  <style>
    circle {
      fill: yellow;
      stroke: black;
      stroke-width: 3px;
    }
    @media (prefers-color-scheme: dark) {
      circle {
        fill: black;
        stroke: yellow;
      }
    }
  </style>
  <circle cx="50" cy="50" r="47"/>
</svg>

Source at tomoyac.com

SVG favicon is still an advanced feature. It is already supported by Firefox and by Chrome, but other browsers do not support it yet.

Parrett answered 21/4, 2018 at 9:30 Comment(10)
How about desktop browsers with dark theme? i.e.: dark mode in Firefox Developer, Chrome Canary, etc?Centipoise
You mean having two icons, one for light themes and one for dark themes, and the right one is picked depending on the theme in use?Parrett
Yes, provided favicon is very dark, it would be nice to set it to a light version on dark themes, and vice versa. Looks like the only dark themed browser where logo appears semi-decently is Safari on Mojave with dark theme enabled. It surrounds the icon with a light grey rectangle. It doesn't look that well, but it works.Centipoise
I see. This feature cannot be supported with plain HTML, which is the kind of material you expect when creating a favicon for a regular website. Having a mechanism based on user agent would not be enough, as themes are dynamic (ie. you cannot assume Chrome == light). So this would require JS. Why not? But that would be an extra feature which is out of scope at the moment.Parrett
@Centipoise A new trick based on SVG and prefers-color-scheme media query is changing the deal. I have rewritten the answer.Parrett
@Parrett Can you revert the change and add a new answer with the new content? I feel odd about an edit that completely rewrites the approach. Neat tip, btw. I intend to upvote.Margoriemargot
@Michael I understand your concern. The thing is: my previous answer was completely deprecated. It was a poor workaround and was recently downvoted (this is why I reviewed it and realized it needed to be rewritten). I would rather delete the previous answer than leaving it as it was for historical reasons, really. When I rewrote it, the answer had a score of zero, which makes me feel that the operation is somehow okay, as the new content is not affected by the previous one in terms of popularity, if you see what I mean.Parrett
🤷 Okay. I'm not going to make a big deal of it. You may want to add a caveat that this only works in FF for now. (With Chrome expected in v80 in February.)Margoriemargot
@Michael That's right! I've just added a note, thank you for the tip and links.Parrett
I didn't get the media query to work in Chrome v88. It uses the svg, but the media query does not work. It works fine in Firefox and Opera. Vivaldi seems to just use favicon.ico located on root, and totally ignoring any <link rel="icon" ...> references.Dacron
O
-1

Hi @richardwestenra,

With PHP placed within the HTML part of a header.php file, to the best of my understanding, this could be done.

First I would assure the $_SERVER['HTTP_USER_AGENT'] is not null, and once it passed that , I would have a second IF for a word in the user_agent: ( strpos ($_SERVER['HTTP_SEC_CH_UA'], 'Google' ).

The below code is how I'm going to implement it, hoping for it to work:

<?php if($_SERVER['HTTP_USER_AGENT'] != null) : ?>

    <?php if (strlen(strstr($_SERVER['HTTP_USER_AGENT'],"Googlebot")) > 0 ) : ?> 
        <meta property="og:image" itemprop="image" content="https://currenge.com/wp-content/uploads/2019/10/favicon_512_512_png.png" />
        <meta property="og:image:width" content="512" />
        <meta property="og:image:height" content="512" />
        <meta property="og:image:type" content="image/png" />
        <meta property="og:image:secure_url" itemprop="image" content="https://currenge.com/wp-content/uploads/2019/10/favicon_512_512_png.png" />
        <meta property="og:image:secure_url:width" content="512" />
        <meta property="og:image:secure_url:height" content="512" />
        <meta property="og:image:secure_url:type" content="image/png" />
    
    <?php else : ?> 
        <meta property="og:image" itemprop="image" content="https://currenge.com/wp-content/uploads/2019/10/favicon_1200_628_png.png" />
        <meta property="og:image:width" content="1200" />
        <meta property="og:image:height" content="628" />
        <meta property="og:image:type" content="image/png" />
        <meta property="og:image:secure_url" itemprop="image" content="https://currenge.com/wp-content/uploads/2019/10/favicon_1200_628_png.png" />
        <meta property="og:image:secure_url:width" content="1200" />
        <meta property="og:image:secure_url:height" content="628" />    
        <meta property="og:image:secure_url:type" content="image/png" />
    
    <?php endif; ?> 
    
<?php endif; ?> 

May I ask , what would you guys say regarding the above possible solution?

Ocieock answered 8/5, 2023 at 7:52 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.