博客上线后,我把整站的视觉细节捋了一遍,最后停在那个最小也最容易被忽视的元素上:浏览器标签页里的 favicon。
第一个目标:明暗自适应
Chrome、Firefox 的标签栏有明暗两种主题,一个黑色图标在暗色标签栏里会直接隐身。SVG favicon 支持内嵌媒体查询,可以做 到「一份文件、两副面孔」:
<style>
path { fill: #0c0c0c; } /* 浅色标签栏: 深色图标 */
@media (prefers-color-scheme: dark) {
path { fill: #fafafa; } /* 深色标签栏: 米白图标 */
}
</style>
现代浏览器都认这套,Safari 除外——它只认 ICO。所以还需要一套静态兜底:ICO 和苹果触屏图标统一用品牌深底配色,反正 Safari 用户看到的是固定的,那就让它固定得体面。
PIL 的 ICO 之坑
静态图标我用 Pillow 生成。想当然的写法是拿最大那张图分别缩放存进去:
img.save("favicon.ico", sizes=[(16,16),(32,32),(48,48),(64,64)])
结果文件只有 186 字节——PIL 悄悄只存了一帧,而且是最小的那种。它不会报错,不会警告,只会让你在线上打开放大后发现糊成一团。
正确姿势是以目标尺寸为基准逐张生成,最大的那张作为基底:
base = draw_monogram(64) # 以最大尺寸作画
base.save("favicon.ico",
sizes=[(16,16),(32,32),(48,48),(64,64)])
一晚上的调试换来一条朴素的经验:多帧 ICO 的大小应该和帧数成正比。186 字节的多尺寸 ICO,一定是哪里不对。
自查清单
图标这种小东西,改完不等于做对。我的自查流程:
- 多底色预览:把 96px 图标分别贴在浅色、深色的模拟标签栏上,缺一个都不算检查过
- 小尺寸放大:16px 的图 nearest 放大 4 倍看锯齿和可辨识度
- 线上复核:部署后
curl -I三个格式(svg/ico/png)都 200,再开无痕窗口强刷
值得吗
一个 32×32 的图标,前后折腾了一晚。理性说,几乎没有访客会注意它;但打开自己站点时标签栏里那个清晰的小方块,是整个网站给我的第一眼反馈。
自托管的乐趣,一半来自访客看到的东西,另一半来自只有自己知道的地方。
Suggest an edit
最后更新:30 Aug 2026
