智能网页设计。第一部分:亮/暗模式图标。

2025-06-10

智能网页设计。第一部分:亮/暗模式图标。

如今,我们拥有了一项超酷的新功能,可以检测操作系统 UI 主题并根据主题更改网站视图。这让我们能够运用新技术编写可主题化且易于自定义的 CSS 和 HTML 代码。在本系列文章中,我将向您介绍如何为您的 Web 应用创建简单的可主题化设计。

虽然我们可以使用 CSS 和 HTML 更改页面的可视化效果,但有一个元素仍然不具备这种能力。你应该知道我在说什么了。没错,它就是网站图标 (favicon)。

如果你在黑暗模式下查看 Dev.to 或 Github 的图标,你会发现它们几乎看不见了。我们需要改变它,让图标在主题切换时做出反应。最合理的方法是使用medialink 元素的属性,它允许图标对传入属性值的 CSS 媒体查询做出反应。但遗憾的是,link 的 media 属性支持的媒体查询列表并不包含prefers-color-scheme

幸运的是,我们可以使用 JavaScript 来实现它。那就开始吧。

这是其工作原理的实时预览。

TL;DR对于那些想要现成解决方案的人,请使用该库:

GitHub 徽标 rumkin / favicon-switcher

使图标对媒体查询做出反应

聆听主题切换

我们需要从页面头部收集所有链接元素,获取media其属性并使用window.matchMedia()方法进行匹配。此方法返回MediaQueryList,它允许监听更改,我们将使用它:

window.matchMedia('(prefers-color-scheme:light)').addListener((e) => {
  e.matches // Determine wether query matched or unmatched
})
Enter fullscreen mode Exit fullscreen mode

添加图标

现在我们需要在页面主体中插入不同主题的图标:

  <link rel="icon" media="(prefers-color-scheme:dark)" href="favicon-dark.png" type="image/png" />
  <link rel="icon" media="(prefers-color-scheme:light)" href="favicon-light.png" type="image/png" />
Enter fullscreen mode Exit fullscreen mode

切换图标

要使浏览器切换标签页的图标,只需将元素设置为 中的<link>最后一个元素即可。这可以正常工作,但 Chrome 目前存在一个 bug,在某些情况下会导致图标切换中断。为了避免此 bug,我们需要创建新的 元素并将其附加到 head 子元素列表中,放在其他链接之后。<link><head><link>

const favicon = document.createElement('link')
link.setAttribute('rel', 'favicon icon')
head.appendChild(link)

// Listen media change
window.matchMedia('(prefers-color-scheme:light)')
.addListener((e) => {
  if (! e.matches) {
    return
  }
  // Apply new favicon source
  const source = document.querySelector('link[rel*="icon",media="(prefers-color-scheme:light)"]')

  if (source === null) {
    return
  }

  link.setAttribute('type', source.type)
  link.setAttribute('href', source.href)
})
Enter fullscreen mode Exit fullscreen mode

只需复制最后一个表达式并替换light即可dark启用黑暗主题图标。

注意!我们检查来源是否是null由于可能的 DOM 突变造成的。

结论

现在您知道如何制作页面图标来对主题切换做出反应。


感谢阅读。使用favicon-switcher可以涵盖更多用例,并支持其他媒体查询,例如max-widthmin-width等。

致谢

照片由Linda XuUnsplash上拍摄

鏂囩珷鏉ユ簮锛�https://dev.to/rumkin/smart-web-design-part-i-light-dark-mode-favicon-31f0
PREV
为什么公司要求员工有热情?
NEXT
我创建了一个暴力破解工具,学习并发编程。