如果你正在为你的网站建立图标系统,有几种选择。如果这些图标都是位图,那么你很可能选择 CSS Sprites 来实现。但如果图标是矢量的,就有两个方案可供选择,行内 SVG 和字体图标。

让我们来对比一下它们的区别。

矢量图标

矢量图标拥有的优势就是,放大缩小质量都不会损失,retina 屏下显示锐利,而且文件大小也比较小。

字体图标 行内 SVG
浏览器将它当做字体,进行抗锯齿处理,导致图标不够清晰 正常的矢量显示

CSS 控制

字体图标 行内 SVG
可以通过font-sizecolor,shadows, rotation 等来控制 可以用于控制 SVG 的 CSS 跟字体图标一样,但更好的是,你可以控制一个由多部分组成的图标的其中一些部分,还可以使用 SVG 专用的 CSS 属性,比如 stroke。

SVG 这方面最大的好处应该是可以实现多色图标。

定位

字体图标 行内 SVG
定位一个字体图标是很烦人的。图标是通过伪元素插入的,并且由line-height, vertical-align, letter-sacing, word-spacing还有字体如何设计(图标周围是不是有一些空间?是否设置了字间距?)来决定它的位置的。然后伪元素的display属性也会影响定位。 SVG 盒子的大小就是实际大小

伪元素盒子的位置并完全是字形的位置

伪元素盒子的位置并不完全是字形的位置。

SVG 盒子大小就是 SVG 实际的大小

SVG 盒子大小就是 SVG 实际的大小。

载入错误

字体图标 行内 SVG
字体图标可能因为没有正确的 CORS 头跨域载入失败,其他原因还有网络拥堵、服务器出错等等。Chrome 有一些 bug 会导致忽视 @font-face 的值而显示回退的字体。而有一些浏览器干脆不支持 @font-face。字体显示失败是非常常见的,失败的原因多种多样。而且,如果你尝试将图标映射到“私有使用区域”,可能会有显示一个 emoji 表情这样奇怪的事发生,因为你用的环境跟 emoji 所用的重合了。或者 emoji 直接推翻你的字形了。 行内 SVG 就在文档里。如果浏览器支持,就能显示。

被迫错误

字体图标 行内 SVG
代理浏览器如 Opera min 和 UC 浏览器不支持 @font-face。有些用户会强制将自己的字体覆盖网页字体。有些拦截程序会阻止自定义字体 即使是那些代理浏览器也支持 SVG,而拦截程序不会阻止 SVG

语义化

字体图标 行内 SVG
一般来说,你会通过给一个span标签设置伪元素来引入字体图标,一定程度上违反了语义化的标准 图标就是小的图片,而svg就能表示图片的意思

可访问性

字体图标 行内 SVG
使用别人的做好的字体图标不是很可靠(太多用不到的图标),而创建自己的图标又不是很方便 SVG 用纯手工或者工具比如 IcoMoon 都是很方便的

浏览器支持

字体图标 行内 SVG
IE6 以上都支持 IE8 以下,Android 2.3 以下不支持

总结,如果可以接受 IE9 以上和 Android 3 以上的兼容性,行内 SVG 比字体图标好得多。如果要支持更多的浏览器,SVG 的降级做法成本又太高了。