你上传了 SVG favicon、两张 PNG 备用图,还为旧浏览器准备了一个 ICO——结果 Safari 在标签页里依然显示那个 ICO。文件本身没问题。问题出在你的 favicon link 标签顺序上。

浏览器并不会直接抓取它们看到的第一个 <link> 标签。根据 WHATWG HTML 规范,用户代理会根据 sizes、media 和 type 属性来挑选最合适的图标。当多个图标匹配度相同时,浏览器可能会使用最后声明的那个。这意味着 link 标签的顺序是一个真正起作用的关键开关,而不是单纯的风格选择。

前置条件

你需要能访问站点的 HTML <head>,并且至少准备两个 favicon 文件(SVG、PNG 或 ICO)。具备 HTML link 标签的基础知识会有帮助——如果需要复习,可以参考我们的 favicon HTML 代码示例速查表。

分步骤操作:排列多个 favicon link 标签

步骤 1:理解浏览器的选择规则

浏览器会根据当前上下文对每个声明的图标打分:显示密度、标签页尺寸、深色模式偏好,以及所支持的格式。得分最高者胜出。打平时,默认取最后一个匹配的声明。一组顺序混乱的标签栈,可能导致现代浏览器跳过你那张清晰锐利的 SVG,反而去抓一张模糊的 PNG——哪怕它们完全支持矢量格式。

步骤 2:从最具体到最通用排列

把能力最强的格式放在最前面,把通用的兜底格式放在最后:

&lt;link rel='icon' type='image/svg+xml' href='/icon.svg'&gt;
&lt;link rel='icon' type='image/png' sizes='32x32' href='/icon-32.png'&gt;
&lt;link rel='icon' type='image/png' sizes='16x16' href='/icon-16.png'&gt;
&lt;link rel='icon' href='/favicon.ico'&gt;

SVG 排在最前面,因为它可以适配任意像素密度。PNG 兜底放在后面,照顾那些不支持 SVG favicon 的浏览器。ICO 放在最后,作为那些不声明格式的旧系统的通用兜底。

步骤 3:加上 type 属性以消除歧义

如果没有 type,浏览器可能会默认按 ICO 格式处理(这是历史上的默认假设),从而直接跳过你的 PNG 或 SVG。加上 type='image/svg+xml' 或 type='image/x-icon' 后,浏览器就能准确知道该期待什么,从而在下载前跳过不兼容的文件。

步骤 4:用 sizes 匹配真实使用场景

sizes 属性用来描述每个图标所针对的渲染场景。16×16 的 PNG 适合浏览器标签页。32×32 的 PNG 适合任务栏和高 DPI 书签栏。针对 iOS 主屏幕,则需要单独声明一个 Apple Touch Icon:

&lt;link rel='apple-touch-icon' sizes='180x180' href='/apple-touch-icon.png'&gt;

Apple Touch Icon 走的是另一套选择流程,不会和普通 favicon 抢占标签页位置——所以把它放在主 favicon 栈的后面即可。

步骤 5:把深色模式 SVG 放在最前面

如果你支持深色模式,可以用 media 属性声明两个 SVG 变体:

&lt;link rel='icon' type='image/svg+xml' href='/icon-light.svg' media='(prefers-color-scheme: light)'&gt;
&lt;link rel='icon' type='image/svg+xml' href='/icon-dark.svg' media='(prefers-color-scheme: dark)'&gt;
&lt;link rel='icon' type='image/svg+xml' href='/icon.svg'&gt;

在任何给定环境下,只有一个 media query 会匹配,因此浏览器只会选中那一个。未带媒体查询的 SVG 作为最终兜底,照顾那些完全不识别 media query 的浏览器。

常见坑

小结

顺序之所以重要,是因为浏览器会从你的标签栈中挑出最匹配的那张图标,而打平时默认取最后一个声明。把能力最强的格式放最前面,兜底格式放后面,再加上 type 和 sizes 属性消除所有歧义。如果你重排之后图标依然不更新,下一个排查重点通常是缓存。可以使用 Mzu favicondl 生成一份干净、尺寸正确的图标包,跳过手动调整尺寸的繁琐步骤。