Fork me on GitHub
秋染蒹葭

SVG图标的使用姿势:搭建私有图标库

天气转暖了,冬日暖阳让人整个都舒展了,周五了,偷偷摸摸鱼,最近少有的晴天,周末户外走起

闲言少叙,开始正文

随着svg的浏览器兼容性越来越好,图标的使用基本已经都已经是svg方案了。笔者最近自己找麻烦,搭建了一个公司内部的svg治理站点,可以理解为一个私有化的阿里巴巴图标库。在对接历史svg治理的过程中,遇到了各种各样的问题。尤其是面对水平参差不齐的设计师的时候,导入到系统的svg也是五花八门的。除了需要在存储落盘前,将图标”洗干净”,还需要和设计师去沟通svg在前端的一些使用逻辑,让他们给出更规范的svg,这就是本文的背景。

三种图标的引入方式

首先一般第三方组件库都会提供图标组件,比如antd提供了@ant-design/icons,一般在实际使用中是不够用的,这就需要自定义Icon,目前项目中自定义Icon有三种方式

  • 直接import图标.svg文件,然后作为<img>标签渲染
  • svg sprite,通过svg-sprite-loader插件,将指定文件夹内的所有.svg文件组装成一个大的.svg文件,在使用的时候通过use指定symbol
  • 第三种是笔者正在用的方式,相当于第二种的进阶方式,和@ant-design/icons提供的createFromIconfontCN()类似,通过自建svg治理服务,可以简单的使用团队共享出来的svg资源

大多情况下,同一个图标会有三个状态:normal/hover/disabled,每个状态都会对应一种颜色,假如使用了第一种方案,我们就需要三个不同颜色的图标,而且很难实现在hover的时候,颜色transition的效果。而且假如项目接入了主题色的时候,或者设计师要修改颜色的时候,都会很麻烦

相比之下,第二种和第三种方式均使用了svg sprite的方式,可以通过css控制图标的颜色,那么只需要一个图标文件,就能满足不同颜色的需求,相比之下,这种方案比<img>的方案更好一些

如何导出svg

为了开发的方便,前端的很多同学会安装sketch,用sketch导出需要的icon很方便

  1. 设计稿选中图标
  2. 在选中内容的情况下,sketch右下角点击「设为可导出」选项
  3. 格式选择「svg」,点击最下方的导出选中项

简单三步,就可以导出svg文件,但是这样并不够

sketch直接导出文件存在的问题

视觉面积不一致

关于视觉面积的问题可以先看看这篇文章Optical Effects in User Interfaces
一般来说,sketch导出图标是按照图标的边界去导出的,但是图片的形态个不一样,造成图标的各个边界的大小也不一样,比如在下面的例子中,设计师为了保持正方形和圆形的视觉面积的一致,会把圆形的直径做的大一些

sketch按照图标的边界导出,最初导出的正方形icon的尺寸是400,圆形的尺寸是450,如果你直接通过<img>引入icon,在界面的宽度就会是400和450,这样确实可以保持视觉大小和设计稿保持一致,但是图标的位置大概率对不齐了,开发的时候就需要针对这种图标进行特殊处理。

假如设计师想统一调整两个图标大小的时候,比如调整到300,那就很难办了。因为一旦你将两个图标都改成300,那肯定圆的视觉面积较小;正确的做法是将正方形的宽度调整到300,而圆的宽度设置为大约337,相当于手动计算一下对应的尺寸,这也是一个办法。

除了这个问题,还有左右/上下重心的问题,比如三角形图标▶️,它的重心必然是偏左边一些,所以设计图上可能会适当的偏右,这里就不详细解释了。

这个问题的解决方法很简单,将所有的图标放到一个略大一些、统一尺寸的正方形区域内。在使用的时候指定一个统一的宽度就可以了

sketch 导出的 svg 不够「纯」

如果你观察过sketch导出的svg源码,你会发现里面有很多层xml节点,会有一些看不太懂的奇怪的标签和属性,svg代码不「纯」会导致一些问题,比如:

  • 体积更大,比如一些2k左右的图,可以优化到500b以内
  • 难以自定义颜色,有些图标是通过形状+填充(fill)实现的,而有的时候又是线条+描边(stroke)实现的,而我们若要自定义颜色的话,则需要统一指定fill来实现
  • 一些svg的属性不兼容,或者sketch导出的有问题,可能会导致在浏览器里打开的效果都有问题

如何正确输出svg图标

一般的做法是:

  1. 通过sketch导出
  2. 使用Adobe Illustrator(简称“AI”,是Adobe系统公司推出的基于向量的图形制作软件),重新编辑一遍:
    1. 取消所有的「分组」,删除无关标签
    2. 将「描边」统一转换为「轮廓」
    3. 可以将一些形状做一些「合并」等操作
    4. 一般坐完这些事情,最终得到的svg文件内部只有一个<path>标签
  3. 调整画布到一个统一的正方形区域,如果图标本身很特殊可能不需要
  4. 导出svg,并手动删除fill属性的颜色,这是为了可以通过css自定义颜色(彩色图标除外)
  5. 使用svgo命令压缩图标

因为AI有一定的上手成本,可以要求设计师完成前3步,再将svg交付给我们,这里可以参考一下阿里巴巴图标库-绘制规则

图标治理平台

笔者在文章开头的位置,不是提到了搭建了一个图标治理平台吗,治理平台是怎么做的呢?其实和上面的流程一样,前三步也是需要设计师来完成,然后设计师导出svg后直接上传,然后会在后端根据页面的的「是否保留颜色」来控制是否去除fill属性,同时使用svgo进行文件的压缩,完成了这一系列的操作后才会将文件落盘存储

这里画张图简单说一下图标治理平台做了什么事情:

其中下载svg sprite到本地的方式可以参考一下createFromIconfontCN方法的实践,通过加载一个cdn上的js,在这个js中将svg插入到dom中,在组件中直接使用<use>即可完成图标的使用

总结

在项目中使用可svg-sprite-loader或者svgr来管理本地的图标,封装自定义icon,这几本已经满足日常需求了,假如你想将图标都维护起来的话,肯定还是选择部署私有的在线的图标治理平台,自己封装createFromIconfontCN()方法,直接使用cdn上的资源,肯定是最方便的。

假如有想交流部署图标库经验的,欢迎在评论区留言

参考资料
Optical Effects in User Interfaces

本文标题:SVG图标的使用姿势:搭建私有图标库

文章作者:zhyjor

发布时间:2023年01月06日 - 11:01

最后更新:2023年10月11日 - 02:10

原始链接:https://zhyjor.github.io/2023/01/06/Icon图标的正确使用姿势/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

🐶 您的支持将鼓励我继续创作 🐶

热评文章