检测浏览器是否使用暗模式并使用其他图标

agu*_*tin 24 browser google-chrome

Google Chrome 73已发布,并为浏览器添加了“暗模式”支持。我注意到许多图标现在看起来很糟。

暗模式Wikimedia Foundation选项卡屏幕截图

暗模式Codecademy选项卡屏幕截图

有没有一种方法可以检测用户是否使用暗模式并更改图标?

Has*_*own 19

为了使它比Josh 的答案更通用一点,请在浏览器仍然在media本地实现时尝试此操作。(注意JS 中没有硬编码的主题、ids 或media-queries数量;它们都保存在 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)">
Run Code Online (Sandbox Code Playgroud)
$(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();
    });
});
Run Code Online (Sandbox Code Playgroud)

结果是,一旦支持该属性,您只需删除 Javascript,它仍然可以工作。

我故意分成/favicon.ico?light两个标签而不是一个标签,media="(prefers-color-scheme: no-preference), (prefers-color-scheme:light)"因为一些不支持media永久选择rel="icon"他们看到的第一个的浏览器......而其他人选择最后一个!

  • 如果您删除了 jquery,我会投票给您的答案 (5认同)
  • 我已经超过 10 年没有使用过 jquery 了。我知道使用它的开发人员为零。它已经过时了。我想我会因为过时的信息而投反对票,因为这些信息会用过时的示例误导任何新开发人员。 (4认同)
  • 由于 `addListener()` 已被弃用,请使用 `match.addEventListener('change', swap)` (3认同)
  • 多么狭隘的评论@gman,如果它更适合你,你可以添加答案的javascript版本。 (3认同)

Jos*_*Lee 18

head在Firefox中但不在Safari中从文档的作品中添加和删​​除图标:

Chrome仍在实施中(prefers-color-scheme: dark),因此评审团还没有成立。https://crbug.com/889087。在带有的Chrome 76中--enable-blink-features=MediaQueryPrefersColorScheme,这会在页面加载时正确设置图标,但在暗模式下不会动态响应更改。

Safari在黑暗模式(例如Wikimedia FoundationGithub)中为黑暗图标添加了灰色背景,因此这种变通方法对于提高可读性不是必需的。

  1. 添加两个link rel=icon元素,id以备后用:

    <link rel="icon" href="a.png" id="light-scheme-icon">
    <link rel="icon" href="b.png" id="dark-scheme-icon">
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建一个CSS媒体匹配器:

    matcher = window.matchMedia('(prefers-color-scheme: dark)');
    matcher.addListener(onUpdate);
    onUpdate();
    
    Run Code Online (Sandbox Code Playgroud)
  3. 从文档的中添加/删除元素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();
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • 我希望有一种更好的方法(例如,浏览器探测选项卡颜色并支持链接元素上的属性),因为这不仅在使用没有系统范围暗模式的暗主题(像我一样)时会崩溃,而且还会失败在 Chrome 中默认为深色的隐身标签中。 (3认同)
  • Chrome更新:[动态更新收藏夹图标](https://web.dev/prefers-color-scheme/#reacting-on-dark-mode-changes) (2认同)

Red*_*Red 18

CSS 具有使用prefers-color-scheme媒体功能的主题模式检测:

@media (prefers-color-scheme: dark) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

考虑到这一点,现在您可以使用 SVG 作为您网站的图标:

<link rel="icon" href="/favicon.svg" type="image/svg+xml">
Run Code Online (Sandbox Code Playgroud)

然后您可以使用 CSSprefers-color-scheme媒体功能更新 SVG 图标设计。下面是一个带有圆角的 SVG 矩形,它具有不同的颜色,具体取决于活动主题:

<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>
Run Code Online (Sandbox Code Playgroud)

现在,考虑到当前浏览器对 SVG 图标的支持,旧浏览器需要回退:

<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="icon" href="/favicon.png" type="image/png">
<!-- favicon.ico in the root -->
Run Code Online (Sandbox Code Playgroud)

来自https://catalin.red/svg-favicon-light-dark-theme/

这里也是一个演示:https : //codepen.io/catalinred/pen/vYOERwL

  • 这是一个很好的答案,我认为这将很快成为完成网站图标的标准方式。然而这仍然不完美。问题是,在除深色模式之外的其他情况下,网站图标可以显示在深色背景上。例如,如果应用程序即使在浅色模式下也具有深色主题。希望会有媒体查询背景是否**是深色的,而不仅仅是用户**喜欢**深色背景。 (6认同)