SVG Symbol
用 Symbol 来把 SVG 合并到一个文件几乎是现在最流行的用法。
Symbol 好处
方便
利用 ID 来取图案,所以不用各种计算,可以随便放。
反复利用
这应该是一个不太容易发现的好处,你可以在文件内部继续用<use>
来做图案的各种版本。这样 SVG 的优势更加明显,节省了好多空间。
比如这个博客里用到的社交图案,原本的是只有图案本身。例如这是 Codepen 的图案:
1 |
<symbol id="icon-codepen" viewBox="0 0 32 32"> |
现在直接在文章里<use>
:
1 |
<svg fill="#000"> |
就是这个效果:
在symbol-defs.svg
里还有它的另外一个版本,带圆圈的,只需要添加几行就可以:
1 |
<symbol id="icon-codepen-circle" viewBox="0 0 32 32"> |
同样的使用方式,既环保又方便:
Symbol 坏处
不完全支持
这种方式并不完全支持 SVG 的各种特性。比如我开始就踩到了一个坑。我的 LOGO 里使用了clippath
,使用这种方式就会失去效果。这个貌似是个陈年老 bug 来的。
解决方式就是利用工具合并路径,最好还压缩成一条,方便管理。编辑工具推荐 Boxy SVG,生成的代码非常轻盈,而且尽可能保留原来的样子,不会像 Illustrator 一样源码面目全非。压缩工具推荐 SVGOMG!,号称 SVGO's Missing GUI。
奇怪的宽高
在宽和高是百分比的情况下,会出现跟<img>
或者普通<svg>
不一样的计算。有时高空出一段,有时宽空出一段。
这个我纠结了很久,没有找到原因。我猜是受到原本整个 SVG 的影响。
解决方法是用相同宽高比的父<div>
来限制;或者不用百分比。
慢
因为零部件是可以<use>
的,所以引擎不能像图片一样直接解析完就一整块到处扔。
虽然这个延时非常的小,一般几乎感觉不到,但是如果像这个博客左边的菜单栏一样(电脑上),在每个页面都是同样的元素,那么切换页面的时候就可以肉眼感受到图案的闪动。这种情况就只能放弃使用 Symbol。可以考虑单独一张 SVG 图片或者:👇
SVG Sprite
SVG Sprite 与以前的 PNG Sprite 一样,把图案按一定方式平铺到一张大图片上。
Sprite 好处
对齐
SVG 不受大小限制,所以 Sprite 可以按统一的规格排列。
取的时候也不受大小限制,利用百分比来取。
比如这个博客左边菜单的图案就是 SVG Sprite,利用 Sass 自动计算百分比。
快
这种方式与普通图片一样肉眼看不到延时,而且还结合了 SVG 不受大小限制的优势。
Sprite 坏处
添加麻烦
图案受位置影响,当然没有 Symbol 方法来得方便。
因为需要快速显示的图案不多,我是利用 Boxy SVG 一个一个添加的。
不太用心的查过一下,没注意到有合适的自动化工具。
能用 Symbol 的当然优先使用 Symbol 方法,所以 Sprite 用的也不多,手动添加可以满足。
有误差
使用百分比因为受小数影响,图案会有1px
浮动,当然这个1px
是根据图案当前大小得出的,所以越小图案浮动的位置越大。
解决方法有两个,一是避免产生小数,按倍数来设置图案大小;二是按图案最小的情况计算出血,把图案缩小空出足够位置。