如何用 Iconfont 创建自己想要的社交图标集合?

前言

  一般来说,我们的个人博客都会放上一些社交图标以及社交链接。这样一来,想要关注我们更多的最新研究或工作的读者就可以很快找到路径。于是,在 Jekyll 博客主题设计的时候,通常会在个人简介的地方放置几个社交小图标,点击社交小图标即可把读者带到你的社交个人主页上。对于不同类型的作者,常用的或者关注的社交平台基本上不大一样,社交小图标也会有不一样的需求。比如说,对于从事科研工作的人来说,像谷歌学术、ResearchGate、ORCID 等等能够列举发表论文或者相关研究的平台就比较重要;对于一般程序员来说,像 Github、Gitlab、Segmentfault、CSDN、简书等等能够展示自己所参与的项目和技术心得体会的平台就比较重要;对于前端设计师来说,像 Instgram、UI 中国、Dribble等等能够展示 UI 设计作品的平台就比较重要。因此,对于一款 Jekyll 博客主题的设计者来说,同时要兼顾到这么多不同的需求可能会有点为难,毕竟领域不同、了解的程度也很有限。

  俗话说得好,授人以鱼不如授人以渔。今天我们就来讲讲如何自己定制一套社交图标集合。

技术发展回顾

图片索引

  对网站前端设计有点了解的小伙伴可能知道,如果要为网站添加一些社交图标,并且支持鼠标悬停高亮显示,最早的办法是采用不同的图片进行切换的方法。具体来说就是,鼠标悬停前是一张图片,悬停后切换到另外一张图片。由于如果要支持很多个社交图标就要准备很多对这样的图片,那么同一页面内的文件 HTTP 请求数就会陡然增加,对页面加载性能有非常大的影响。

  随之产生了一种比较可行的解决方案:将所有的社交图片拼在一张图上,然后通过定位的方式来索引到不同的社交图标,我们通常将这张图称为雪碧图。这种方法的好处比较明显,浏览器只需要发出一次请求下载雪碧图即可,减少了文件 HTTP 请求数,加载时间显著变短。比较明显的困难是,定位找起来简直不要太麻烦。而且为了能描述不同的图标悬停前后的位置,必须写很多对样式与之对应,工作量比较大。另外一个比较大的困难是,图标集合的更新很麻烦。新增图标的时候,为了能沿用原来已经写好的样式,只能在原有的雪碧图的基础上往后增加图标,当然同时也要增加对应的样式。

  虽然雪碧图在某种程度上提升了加载效率,但是给后期的更新、维护带来了不小的麻烦。还有一个越来越凸显的问题——随着访问网站的设备类型的不断增多,图片的质量会影响到不同设备、不同平台下的效果一致性,甚至在高分辨率屏幕下会出现图标模糊的情况,用户体验极其不佳。最有效的改进方法可能就是采用分辨率更高、质量更高的图片来拼凑雪碧图,不过同时也会增大雪碧图的文件体积。这会导致虽然只发出了一个文件 HTTP 加载请求,但是由于文件体积过大、加载速度慢,而给用户带来不好的使用体验。

字体图标

  接着发展出了一种字体图标的东西来解决图片索引中存在的问题。字体图标,顾名思义就是把所有的图标都变成了字体编码一样,只要我们在网页中引入字体图标文件就可以像用 Unicode 一样使用字体图标了。这种方式最好的一点就是,像操纵字体一样设置字体图标的样式。比如说,虽然我们只在字体图标文件中定义了一个图标,但是当我们使用不同的 color 定义时,图标就会改变其颜色。而且,我们操纵字体图标的大小是采用 font-size 的方式而非 width/height 的方式。这样一来,字体图标和行内文字段落一起使用时也是非常匹配的,行距等文字样式都能同等适用。

  当然,字体图标在后期的维护、更新过程中也会有些问题。比如说,对于一个大型项目的迭代开发,每个子系统可能都会弄一套需要的字体图标,然后在代码分支合并时就会出现问题。因此,有些项目团队可能会为此而设定一位管理员来专门管理字体图标的更新。每个子系统只能向图标管理员提交他们的更新,最终更新由图标管理员来完成。虽然这样也能在某种程度上解决问题,但是对于图标管理员来说还是会很苦恼。

  说到这里,有人可能会想起 Bootstrap 等 UI 框架中自带的字体图标集合。那我们直接使用某个框架提供的字体图标集合不就万事大吉了吗?可事实并非如此,框架所包含的字体图标集合虽然看起来还是比较全面,但是还是有可能缺少某些我们想要的字体图标。想到这里,可能会想不如把多个字体图标集合整合在一起使用不就好了吗?这样随之而来的问题是,很大可能存在大量冗余。对于前端界面来说,除了大量的 HTTP 请求是无法接受的,大量冗余代码也是无法接受的。当我们用 Lighthouse 类似的工具来测试网页的性能时,就可以很容易地发现请求代码的使用率情况。如果我们采用多个字体图标集合并用的方案,那么代码实际使用率可能就会很低。也就是说,请求的代码基本上不会在网页中被使用到,这对于优化页面性能来说简直就是噩梦。

  如果我们觉得自己来手动管理、手动更新字体图标文件太麻烦了,其实也可以用阿里的 Iconfont 或者其他类似工具来在线管理字体图标集合。Iconfont 会提供一个阿里 CDN 上的链接地址来直接使用你建立好的字体图标集合,这样一来基本上就解决了上面所说的维护难题。我们在 Iconfont 上更新好字体图标集合后,Iconfont 会生成一个新的链接地址。然后,我们只需要修改页面代码的对应地址就可以非常方便地应用更新。

  这么看来,字体图标的方案好像很完美了,但事实上还是存在其他的问题。Iconfont 这类平台比较适合个人开发者或者开源项目,而对于企业开发者或者非开源项目来说可能依然不大适合。另外,字体图标因为像字体一样被操纵,所以只能支持一种颜色,无法同时支持多种颜色。除此之外,如果我们想要预览所有的图标,但是抱歉的是脱离了 Iconfont 这类平台我们可能就没有办法做到。

Symbol 图标

  实际上除了字体图标在不同设备、不同平台上有相同的效果之外,SVG 图标也具有类似的效果,这主要是因为 SVG 图标的矢量本质,即缩放不会产生任何失真。SVG 图标还支持多种颜色、可以通过字体样式调整样式,并且支持 IE9 以上版本的浏览器。(随着时代的进步,IE 其实已经不是最新的 Windows 11 操作系统默认软件之一了,而且微软也不再提供 IE 安装包下载了,所以未来 IE 浏览器可能不会出现在考虑支持列表里。)为了能够创建一个 SVG 图标集合,我们可以使用 symbol 元素来定义一个图形模板对象,然后用一个 <use> 元素实例化。symbol 元素对图形的作用是在同一文档中多次使用,添加结构和语义。结构丰富的文档可以更生动地呈现出来,类似讲演稿或盲文,从而提升了可访问性。值得注意的是,一个 symbol 元素本身是不会呈现的,只有当 symbol 元素的实例(即,一个引用了 symbol<use> 元素)才能呈现。

  如下代码所示,是一个 symbol 图标的例子。其中,symbol 元素定义了两个圆圈,对应信息如下:

圆的编号 位置 半径 填充色 描边宽度 描边颜色
1 (50, 50) 40 红色 8 红色
2 (90, 60) 40 白色 8 绿色

实例化了三个 symbol 元素,分别为:

实例编号 位置 宽度 高度
1 (0, 0) 100 50
2 (0, 50) 75 38
3 (0, 100) 50 25
<svg>
<!-- symbol definition  NEVER draw -->
<symbol id="sym01" viewBox="0 0 150 110">
  <circle cx="50" cy="50" r="40" stroke-width="8" stroke="red" fill="red"/>
  <circle cx="90" cy="60" r="40" stroke-width="8" stroke="green" fill="white"/>
</symbol>

<!-- actual drawing by "use" element -->
<use xlink:href="#sym01"
     x="0" y="0" width="100" height="50"/>
<use xlink:href="#sym01"
     x="0" y="50" width="75" height="38"/>
<use xlink:href="#sym01"
     x="0" y="100" width="50" height="25"/>
</svg>

效果如下所示:

vgy.me

创建自定义社交图标集合

  现在让我们来尝试一下借助 Iconfont 来创建自定义的社交图标集合吧。首先访问 Iconfont 首页 并使用 Github 账户或者其他方式登录好。然后在搜索框中输入 github 查询平台所有开放的相关图标,点击即可加入购物车。

vgy.me

  接着点击右上角的购物车按钮如下所示可以查看已加入到购物车的所有图标,并点击添加到项目

vgy.me

  然后给项目取名(这里的名字随便起),点击确认按钮完成项目添加,自动跳转到项目页。

vgy.me

  点击生成代码即可生成专属链接,并出现点击复制代码按钮。

vgy.me

  点击收起在线链接旁边的下箭头可以看到预览字体,点击预览字体即跳转到在线预览页面,如下所示。

vgy.me

  这里提供了三种方式来使用创建好的社交图标集合,目前平台推荐的是Symbol 引用方式。接着即可按照以下三个步骤在你的网页上轻松使用自定义好的社交图标集合了。

vgy.me

小提示

  如果想要实现鼠标悬停图标高亮的效果,还需要自己修改一下 CSS 样式,如下所示。这里采用了灰度遮罩滤镜的方式,给原来彩色的图标灰度化了。当鼠标悬停时,灰度化效果被移除,并且有 0.2 s 的缓慢过渡。不过如果原来的图标是黑色的话,灰度化的效果可能就比较差,悬停前后的差异不大明显,所以推荐使用彩色社交图标。Iconfont 平台实际上提供了在线编辑修改颜色的功能,如果想要知道某个图标或者品牌的主题颜色可以访问 Schemecolor 来查询。

.icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
    filter: grayscale(100%);
    -webkit-filter: grayscale(100%);
    -moz-filter: grayscale(100%);
    -ms-filter: grayscale(100%);
    -o-filter: grayscale(100%);
    transition: .2s;
}

.icon:hover {
    filter: none;
    -webkit-filter: none;
    -moz-filter: none;
    -ms-filter: none;
    -o-filter: none;
}

参考资料