都 2020 了如果你还没有在项目中使用过 SVG,就好比你没有在项目使用过 REACT 或 VUE 一样。
在不考虑兼容性(IE8+)的情况下,SVG 应该是目前解决项目中图标问题的最佳方案,没有之一。
SVG 在变大变小的情况下不会出现失真(出现锯齿或者看到像素点),也可以像 GIF 一样可以动起来。你不再会有因为同一个图标颜色不同,就要切两张图的困扰。
只要你愿意,你甚至可以用 HTML,CSS,JS 其中任何一个语言,来实时修改你的 SVG 图标,即使是前后两个图标可能长得完全不一样。
我们项目在建站初期直接就选择了 SVG 作为我们图标的解决方案。虽然以上众多好处让我们体会到了它的好,然而在实际项目中还是遇到了一些坑。为了不做标题党,这里总结了我们团队近三年对于 SVG 使用的大大小小的问题。
一、SVG 的几种使用方式
SVG as Img
SVG as Sprite (Iconfont)
SVG in HTML
SVG in CSS
SVG in JS
二、技术方案实际体感
SVG as Img & Sprite
SVG In HTML & CSS
SVG In React
三、SVG In React 交付最佳实践
四、SVG In React 使用最佳实践
五、SVG 的一些坑
一、SVG 的几种使用方式
1. SVG as Img
首先,SVG 可以像 JPG,PNG,GIF 一样,作为图片文件去使用。
<style>[data-icon] {
display: inline-block; width: 1em; height: 1em; background: no-repeat center/contain;}[data-icon][size="24"]{
width: 24px; height: 24px;}[] {
background-image: url("./assets/hello.svg");}style><i aria-hidden="true" size="24" data-icon="hello">i><img src="./assets/hello.svg" width="24" height="24" alt="hello" />
不管是将它作为背景图片,或者是作为的
src
属性都可以。
还可以作为一些 embed object iframe … 等标签等
src
属性,但因为项目中几乎很少用到这里不多做介绍。
2. SVG as Sprite (Iconfont)
我们都知道为了减少图片资源请求数量,会将大多数的小图标合并成雪碧图,然后利用 CSS 控制background-position
的位置来实现不同图标的显示。
对于 SVG 实现雪碧图,当然首推的是iconfont[1]只需要将你的 SVG 文件上传上去,然后点击下载,就能得到合并好的三种不同使用姿势的雪碧图(类似知名的还有icomoon[2])。
方案 | Unicode | Font class | Symbol |
兼容性 | IE6+ | IE8+ | IE9+ |
特点 | 渲染效果不及后两种 | 上手容易,书写直观 | 面向未来 |
基本上现在只需要基于浏览器兼容性,考虑后面两种方案就好。
3. SVG in HTML
SVG 是使用 XML 来描述二维图形和绘图程序的语言。
因为 SVG 本身是 XML 格式的,这个和 HTML 天然类似,所以可以直接将 SVG 内联到 HTML 中。
<svg width="50" height="50" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg"><rect width="50" height="50" fill="#ff0000"/>svg>
比如你想画长宽都是50px 的正方形,你只需要将上面的代码粘贴到 HTML 即可。想要改变颜色,或者尺寸只需要修改对应属性即可,是不是非常的直观和方便。
这也是 SVG 相对于其它图片格式,除开矢量特性之外的另一个不可替代的优势。可是我们的图标往往不是只使用一次,也并不是每个图标的 HTML 代码量都这么少,如果想通过直接复制粘贴来达到复用的效果就比较的麻烦。
既然是对于 HTML 的复用,那么比较最简单的易行的方式就是使用HTML模版引擎,这里以 nunjunks 举例。
{% macro ISquare(color='red', size='16')