如何实现Favicon:适合大多数需求的六个文件

910 阅读8分钟

编者按:随着新的一年的到来,这篇文章被稍微修改了一下,以反映出这些内容仍然是有意义的!

现在是时候重新思考我们如何为现代浏览器制作一套收藏夹,并停止图标生成器的疯狂行为。前端开发人员目前不得不处理20多个静态PNG文件,只是为了在浏览器标签或触摸屏上显示一个小小的网站标志。继续阅读,看看如何采取更聪明的方法,采用一套适合大多数现代需求的最小图标。

事实证明,关于favicons的话题比任何人所希望的都要详尽,所以我也将整篇文章总结为两个代码段,供那些已经吃够了苦头的人参考,他们知道该怎么做。不过,我还是推荐大家去看其余的内容

极短的版本

你不需要提供几十个图标,而只需要五个图标和一个JSON文件。

对于使用HTML的浏览器。

<link rel="icon" href="/favicon.ico" sizes="any"><!-- 32×32 -->
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png"><!-- 180×180 -->
<link rel="manifest" href="/manifest.webmanifest">

而在你的网络应用清单中。

// manifest.webmanifest
{
  "icons": [
    { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
    { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
  ]
}

这就是了。如果你想知道我是如何走到这一步的,我不得不做出的妥协,以及如何从头开始一步步地建立这样的一套东西,请继续关注文章的其余部分。

长篇大论,解释一切

favicon的概念,即 "最喜欢的图标 "的简称,自21世纪初以来一直存在。我们都在浏览器的标签栏中看到过这些可爱的小图片,它们帮助我们区分打开的网站。用户希望你的网站有一个favicon。这是那些让其他人认真对待你的小东西之一。

即使是苹果公司,也一直对并非来自库比蒂诺的图标有某种审美上的不满,多年来一直淡化Safari浏览器中的favicon,现在终于放弃了,并在其所有的设备上正确显示它们。

如果你有一个面向公众的网站,它就必须有一个favicon。可悲的是,用户所认为的一个图标实际上是很多个。

因此,人们通常会把为不断增加的屏幕和设备生成这些必要文件的艰巨任务交给favicon生成工具。没有人在正常情况下会想花几个小时来手工创建它们。毕竟,我们在这里是为了建立网站,而不是为了让浏览器供应商高兴。

A set of favicons generated by a popular online generator

一组由流行的在线生成器生成的favicons

作为NanoID的创建者和极简主义开源的倡导者,我倾向于从一个稍微不同的方向思考。什么是最有效的网站图标集?哪些格式已经过时了?哪些图标类型可以用小的妥协来代替?

因此,我着手创建一个最小的图标列表,在所有情况下和所有浏览器中都能使用--除了一些边缘情况--即使如此,这仍然可以使用,只是不是100%完美。

终极Favicon设置

我决定依靠SVG和浏览器的缩小功能来代替创建许多不同尺寸的图片。如果你担心性能问题,我在这里把话说清楚。

  • 浏览器在后台下载favicon,所以一个更大的favicon图片不会影响网站性能。
  • 对于那些本来就不应该是位图的图片来说,SVG是减少图片尺寸的一个好方法;对于许多标识来说,所产生的文件会比PNG小得多。
  • 在这个最小的集合中只有三个PNG图像,你可以使用高级工具来优化它们的大小。这为那些没有无限数据计划的互联网用户解决了一个问题。

现在我将揭示我在研究和实践中得出的最小图标集。这个列表应该适用于所有流行的浏览器和设备,包括旧的和新的。

一、用于传统浏览器的favicon.ico

ICO文件实际上有一个目录结构,可以打包不同分辨率的文件。我建议坚持使用一张32×32的图片,除非你手中的图片不能很好地降级到16×16(比如说,如果它变得模糊不清)。在这种情况下,你可以要求你的设计师想出一个特殊版本的标志,以适应小像素网格。

https://example.com 网站应该有一个favicon,https://example.com/favicon.ico 。不要自作聪明地使用文件夹静态资产文件夹结构和缓存克星。一些工具,如RSS阅读器,只是从服务器上请求/favicon.ico ,而不去寻找其他地方。

我们需要sizes="any" ,用于<link>.ico 文件,以便修复Chrome浏览器选择ICO文件而不是SVG的错误

II.为现代浏览器提供一个单一的SVG图标,并有一个浅色/深色版本

SVG是一种描述曲线而非像素的矢量格式。在大尺寸下,它比光栅图像更有效率。截至目前,72%的浏览器都支持SVG图标。

你的HTML页面应该有一个<link> 标签,在它的<head>rel="icon"type="image/svg+xml" ,并在href ,包含一个指向SVG文件的链接作为属性。

SVG是一种XML格式,可以包含一个<style> 标签来描述CSS。与任何CSS一样,它可以包含媒体查询,如@media (prefers-color-scheme: dark) 。这将允许你在浅色和深色系统主题之间切换同一个图标。

III.用于苹果设备的180×180 PNG图像

如果你将网页作为快捷方式添加到iPhone或iPad的主屏幕上,苹果触摸图标是苹果设备会使用的图像。你的HTML页面内应该有<link rel="apple-touch-icon" href="apple-touch-icon.png"> 标签<head>

自iOS 8+以来,iPad需要一个分辨率为180×180的图片。其他设备会将其降级,但如果我们提供的源头质量足够高,降级不会对最终用户造成伤害(我稍后会回到这个问题)。

小提示:如果你在图标周围放置20px 填充物,并添加一些背景颜色,苹果触摸图标会看起来更好。你可以使用任何图像编辑器来做这个。

四。带有192×192和512×512 PNG图标的安卓设备网络应用清单

  • 网络应用清单是一个JSON文件,包含浏览器将你的网站安装为系统应用的所有细节。这种格式是由谷歌通过其PWA倡议产生的。
  • 您的HTML页面应该有一个<link rel="manifest" href="path.webmanifest"> 标签,上面有一个指向清单文件的链接。
  • 清单应该有一个icon 字段,链接到两个图标。192×192,用于在主屏幕上显示,512×512,将在PWA加载时作为闪屏使用。
{
  "icons": [
    { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
    { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
  ]
}

我们有没有忘记谁?

当然,还有更多的图标样式,其中一些是非常模糊的,所以让我们看看我们的设置与它们的关系如何。也许,现在是时候向一些不太成功的格式说再见了。

Windows磁贴图标

微软Edge曾经支持一种特殊的图标格式,将网站钉在开始菜单上。对于最近版本的Windows来说,这不再是必需的。

Safari的钉子图标

Safari以前有一个SVG单色图标的要求,用于钉住的标签。然而,从Safari 12开始,我们可以为固定标签使用普通的favicon。即使是apple.com也不再使用mask-icon

rel="快捷方式"

很多(现在已经过时的)教程都会将favicon.ico ,变成这样的HTML。

<link rel="shortcut icon" href="/favicon.ico" sizes="any">

请注意,shortcut 不是,而且从来都不是,一个有效的链接关系。请阅读Mathias Bynens十年前的这篇精彩文章,它解释了为什么我们从来不需要快捷方式,以及为什么rel="icon" 就可以了。

Yandex Tableau

Yandex浏览器是一个基于Chromium的浏览器,来自俄罗斯最大的搜索引擎。在俄罗斯,它拥有20%的市场份额。它有一个很好的功能,允许网站通过yandex-tableau-widget 链接提供的特殊JSON清单,在主屏幕上的小工具中显示实时数据。然而,这一功能被证明不是很受欢迎,Yandex现在已经从其网站上删除了相应的技术文档。普通的图标清单也会有同样的效果。

歌剧海岸

过去,iOS的实验性浏览器Opera Coast需要一个特殊的228×228图标。这个浏览器在2017年离开了App Store,我怀疑它在那之后的多次iOS更新中幸存下来。

现在,当我们向死去的战友挥手告别时,让我们看看如何为那些仍然站立的人制作一个终极favicon集。

如何建立我们的终极图标集

以下是如何通过六个快速步骤建立我们的终极、简约的favicon套装。所有你需要开始的是一个你想使用的标志的SVG文件。

第1步:准备好SVG

要确保SVG图像是正方形的。在你的系统浏览器中打开源文件,检查图像的宽度和高度。使用任何SVG编辑器来调整SVG的大小都很容易。在Inkscape中,你可以通过选择 "文件"→"文件属性 "来改变文件的大小,然后用 "对象"→"对齐和分布 "来将标识居中。

将你的文件保存为icon.svg 。现在让我们来摆弄一下我们的SVG,让它与现代系统主题很好地配合。问问你的设计师,对于深色的主题,颜色应该如何倒置(对于黑白的标志,你只需将黑色改为白色)。

现在,在一个文本编辑器中打开你的SVG文件。找到一个<path> ,其中有一个深色或缺失的fill 。添加一个CSS媒体查询,它将在主题变化时触发,并将fill ,变成你想要的颜色。

  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
+   <style>
+     @media (prefers-color-scheme: dark) {
+     .a { fill: #f0f0f0 }
+     }
+   </style>
-   <path fill="#0f0f0f" d="…" />
+   <path class="a" fill="#0f0f0f" d="…" />
  </svg>

第2步:创建一个ICO文件

在一个光栅图形编辑器中打开你的icon.svg 文件。我推荐GIMP;它是免费的、多平台的。

接受将SVG渲染成栅格。设置宽度和高度为32像素。将文件导出到favicon.ico ,使用32bpp,8位alpha,没有调色板设置。

如果你没有GIMP,你可以安装InkscapeImageMagick,在终端将SVG转换为ICO。

inkscape ./icon.svg --export-width=32 --export-filename="./tmp.png"
# In Windows call `magick convert ./tmp.png ./favicon.ico`
convert ./tmp.png ./favicon.ico
rm ./tmp.png

将图像缩小到16×16,并检查图标的可见性。如果它已经变得太模糊了,最好向你的设计师要一个定制的微小版本的标志。

要包括一个单独的16×16版本的图标。

  1. 用32×32的图标打开favicon.ico
  2. 创建一个16×16大小的新层。
  3. 把16×16版本的图标放到这个层里。
  4. 导出该文件。GIMP会将每个布局保存为单独的图标版本。

或者你可以通过在ImageMagick中做同样的事情。

convert ./icon-32.png ./icon-16.png ./favicon.ico

第3步:创建PNG图像

再次在光栅图形编辑器中打开你的源SVG文件,创建一个512×512的图像。将其导出为icon-512.png 。将
图像缩放为192×192,并导出为icon-192.png 。现在将图像本身缩放为140×140,并将画布设置为180×180,然后将其导出为apple-touch-icon.png

或者你可以在Inkscape中做同样的事情。

inkscape ./icon.svg --export-width=512 --export-filename="./icon-512.png"
inkscape ./icon.svg --export-width=192 --export-filename="./icon-192.png"

第四步:优化PNG和SVG文件

优化SVG的最好工具是SVGO。要使用它,请运行。

npx svgo --multipass icon.svg

Squoosh是一个很好的优化光栅图像的网络应用。

  1. 在Squoosh中打开你的icon-512.png
  2. 将压缩设置改为OxiPNG
  3. 启用 "减少调色板"。
  4. 设置64种颜色。
  5. 通过移动滑块来比较之前/之后的情况。如果你看到有区别,增加颜色的数量。
  6. 保存该文件。

icon-192.pngapple-touch-icon.png 重复这些步骤。

第5步:将图标添加到HTML中

你需要将favicon.icoapple-touch-icon.png 的链接添加到你的HTML中。

对于静态的HTML。

  <title>My website</title>
+ <link rel="icon" href="/favicon.ico" sizes="any">
+ <link rel="icon" href="/icon.svg" type="image/svg+xml">
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png">

然而,我们建议使用捆绑器来生成缓存破译器(在名称中包括文件的哈希值作为指纹)。如果你使用Webpack与[html-webpack-plugin]。

  1. 创建一个index.html 模板。

  2. 将该模板添加到插件选项中。

    new HtmlWebpackPlugin({ template: "./view/index.html" });
    
  3. 定义一个带有链接的HTML模板(例子中使用HtmlWebpackPlugin来包含文件,但它可以是你选择的模板语言)。

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>My website</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <link rel="icon" href="/favicon.ico" sizes="any">
        <link rel="icon" type="image/svg+xml" href="<%=
          require('./icon.svg').default
        %>">
        <link rel="apple-touch-icon" href="<%=
          require('./apple-touch-icon.png').default
        %>"
       >
      </head>
      <body></body>
    </html>
    
  4. 使用 copy-webpack-plugin来复制favicon.ico ,而不在文件名中添加哈希值。

额外的提示:创建一个单独的图标,用于分期付款

Favicons是一个很好的方法来区分你的生产环境和暂存环境。我发现,使用一个替代的图标,对于避免任何昂贵的混淆情况是超级有效的。

用相同的标志创建一个favicon-dev.ico ,但要反转颜色(或做一些对你有意义的事情)。对SVG做同样的处理,创建icon-dev.svg

现在,根据process.env.NODE_ENV === 'production' 的情况,在你的HTML模板中替换图标。


  <!doctype html>
  <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>My website</title>
      <meta name="viewport" content="width=device-width,initial-scale=1">
-     <link rel="icon" href="/favicon.ico" sizes="any">
+     <link rel="icon" sizes="any" href="<%=
+       process.env.NODE_ENV === 'production'
+         ? '/favicon.ico'
+         : require('./favicon-dev.ico').default
+     %>">
      <link rel="icon" type="image/svg+xml" href="<%=
-       require('./icon.svg').default
+       process.env.NODE_ENV === 'production'
+         ? require('./icon.svg').default
+         : require('./icon-dev.svg').default
      %>">
      <link rel="apple-touch-icon" href="<%=
        require('./apple-touch-icon.png').default
      %>">
    </head>
    <body></body>
  </html>

第6步:创建一个网络应用程序清单

对于静态HTML,创建一个名为manifest.webmanifest 的JSON文件。

{
  "name": "My website",
  "icons": [
    { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
    { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
  ]
}

在你的HTML中链接它。

  <title>My website</title>
+ <link rel="manifest" href="/manifest.webmanifest">
  <link rel="icon" href="/favicon.ico" sizes="any">
  <link rel="icon" href="/icon.svg" type="image/svg+xml">
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">

使用Webpack,你可以使用webpack-pwa-manifest插件。

  plugins: [
    …,
    new WebpackPwaManifest({
      name: 'My website',
      icons: [
        { src: resolve('./icon-192.png'), sizes: '192x192' },
        { src: resolve('./icon-512.png'), sizes: '512x512 }
      ]
    })
  ]

谢谢您的阅读!正如你所看到的,有了现代网络标准,创建我们的终极Favicon集的任务就变得相当简单了。而且,尽管手动遵循这些步骤不应该花费你太多的时间,但有一个自动化的工具来做同样的事情会让事情变得更加神奇如果你愿意建立一个,请随时在Twitter上与我联系;我将非常乐意提供帮助。