透明背景上的黑色标志在浅色标签页中效果很好,但在深色标签页中就消失了。ICO 格式无法自适应,而 SVG 网站图标可以:它能够包含一条根据浏览器主题切换颜色的 CSS 规则。

问题:一个文件,两种背景
如今浏览器会跟随系统主题,同一个页面的标签栏,对一位访客可能接近白色,对另一位访客却接近黑色。为其中一种背景设计的单色图标,在另一种背景上就难以辨认。
许多网站通过给图标添加不透明的彩色背景来规避问题。这样确实有效,但图标会变成厚重的色块,而大品牌通常只保留背景透明的符号。
合适的办法是让浏览器自行选择,而且无需 JavaScript,也无需服务器端检测。
自适应 SVG 如何工作
SVG 文件是一份文档,并非单纯的平面图片:它可以包含 style 标签,因此也可以包含媒体查询。在其中添加 prefers-color-scheme: dark 规则,即可在浏览器使用深色主题时重新定义路径的填充颜色。
实际使用时,SVG 先声明浅色主题下的默认颜色,再用一条规则在深色模式中替换它。浏览器会在渲染时应用合适的颜色,访客切换主题后也会立即更新标签页。
同一机制还能实现更复杂的变化,而不仅是反色:例如浅色模式使用镂空符号,深色模式则使用实心徽章,两种模式显示完全不同的图形。
同时声明 SVG 和 .ico
使用 link rel="icon" type="image/svg+xml" href="/favicon.svg" 声明 SVG。支持它的浏览器会优先使用,不支持的浏览器则退回根目录下的 favicon.ico。
因此无需删除任何文件:两种格式并存,分别覆盖不同客户端。这就是将渐进增强应用于一个 32 像素图标。
有一点需要注意:网站图标 SVG 必须独立完整。此场景不会加载外部字体、远程图片或脚本。文字需要转换成轮廓。
深色模式版本的适用范围
深色模式版本适用于桌面浏览器的网站图标,不会影响使用固定不透明 PNG 的 Apple Touch 图标,也不会影响由 Android 在自身背景上渲染的网页应用清单图标。
支持情况也并非完全一致:基于 Chromium 的浏览器和 Firefox 会读取自适应 SVG,Safari 的支持则取决于版本。由于会自动退回 .ico,这并不会阻止图标显示。
因此,请先设计好所有访客都能看到的默认浅色模式图标,再将深色模式版本作为支持它的浏览器中的优化。
一手资料
常见问题
favicon.ico 能处理深色模式吗?
不能。ICO 存储的是固定的位图,没有主题概念。只有 SVG 能包含媒体查询,因此现代图标组合会同时提供这两种格式。
需要浅色和深色两个 SVG 文件吗?
不需要,一个文件就够。两种版本放在同一个 SVG 内,由 prefers-color-scheme 媒体查询区分,可以避免额外请求和检测代码。
如何测试深色主题效果?
切换操作系统主题,再重新加载标签页。生成器中并排显示浅色与深色标签页预览,可以省去反复切换。