前言
由于SVG自身的矢量性质,不管在什么情况下,图标都很清晰,可以适应不同尺寸大小和不用分辨率。不用担心模糊和锯齿。同时还能更改图标的填充颜色。
CSS sprite 和SVG Sprite
传统的CSS sprite可以分为图片和字体图片。
图片是将所有的icon整合到一张图中,然后通过定位获取其中的某个图标。有点是管理简单,网络请求少。缺点是无法更改图标的样式,在高分辨率的屏幕下看和周围的样式比较起来有点模糊。而且大于图标原图大小的渲染也会导致图片模糊。所用同样的图标有时需要制作很多个。
相对来说字体图标会好很多。字体图标的基本原理是将Icon定义为图片字体, 在CSS中用@font-face引入Icon Font自定义字体, 再利用font-family和字符码显示出指定的图标。
字体图标的意思就是这个图标类似字体,我们可以设置他的gont-size和color等。但字体图标有字体图标的缺点,就是只有一个颜色,无法设置复杂颜色的图标。
SVG图标具备图片图标和字体图标的有点,可以更改样式同时保证清晰。
SVG sprite
symbol标签
symbol元素在SVG雪碧图的使用中,属于用于定义图片内容。
- symbol元素用来定义一个图形模板对象,它可以用一个元素实例化。symbol元素对图形的作用是在同一文档中多次使用,添加结构和语义。结构丰富的文档可以更生动地呈现出来,类似讲演稿或盲文,从而提升了可访问性。注意,一个symbol元素本身是不呈现的。只有symbol元素的实例(亦即,一个引用了symbol的 元素)才能呈现。
- symbol里面可以添加任意的svg元素,包括动画,除了不显示外基本和svg标签差不多,同样可以设置viewbox这些属性。
- 我们在定义图标时,每一个symbol代表一个图标。
<svg>
<symbol id="svg-test" viewBox="0 0 26 26">
<desc>居中对齐</desc>
<path d="M7,9h12c0.5,0,1-0.5,1-1s-0.5-1-1-1H7C6.5,7,6,7.5,6,8S6.5,9,7,9z"/>
<path d="M19,17H7c-0.5,0-1,0.5-1,1s0.5,1,1,1h12c0.5,0,1-0.5,1-1S19.5,17,19,17z"/>
<path d="M10,12c-0.5,0-1,0.5-1,1s0.5,1,1,1h6c0.5,0,1-0.5,1-1s-0.5-1-1-1H10z"/>
</symbol>
<symbol id="svg-tool-stroke-5" viewBox="0 0 30 16" >
<desc>描边5</desc>
<rect x="-10" y="6" width="7" height="2"/>
<rect x="-1" y="6" width="2" height="2"/>
<rect x="3" y="6" width="7" height="2"/>
<rect x="12" y="6" width="2" height="2"/>
<rect x="16" y="6" width="7" height="2"/>
<rect x="25" y="6" width="2" height="2"/>
<rect x="29" y="6" width="7" height="2"/>
<rect x="38" y="6" width="2" height="2"/>
</symbol>
</svg>
这个symbol也有点想一个SVG,本身里面的内容就是一个完成的图形,同时也是有viewbox属性,这个属性跟svg的viewbox一样。
需要留意的是,symbol里面无法定义defs的,所以如果设计纹理或者渐变之类的图标样式,需要在symbol所在的svg之前,再用一个svg来定义这些填充内容。然后再在symbol里面引用。
use标签
use标签,用于引用在defs标签定义好了的元素。起到重复使用标签的作用。这里可以使用use来使用定义在symbol中的图标。
use标签有两个作用: 1、可重复调用 2、跨SVG调用
<svg>
<defs>
<g id="shape">
<rect x="0" y="0" width="50" height="50" />
<circle cx="0" cy="0" r="50" />
</g>
</defs>
<use xlink:href="#shape" x="50" y="50" />
<use xlink:href="#shape" x="200" y="50" />
</svg>
<svg width="500" height="110"><use xlink:href="#shape" x="50" y="50" /></svg>
use是SVG图标的一个关键点,我们可以把SVG图标全部定义在一个SVG中,统一处理。在需要使用的地方再重新创建一个SVG,通过use标签来调用图标。
这样做的好处是可以降低图标代码的重复使用减少对业务代码的影响。
更改SVG图标的样式
我们可以更改SVG图标的大小和填充色,大小就不用说了
要更改填充色,首先在symbol下定义的图标自身标签上不能带有颜色,然后在使用时我们直接改使用时的svg的fill,这个fill的颜色值会继承到use里面去,也就可以更改图标的颜色。如果我们在symbol里面已经定义好了样色的是无法在使用时更改的。如下:
<svg>
<symbol id="svg-test" viewBox="0 0 26 26">
<desc>居中对齐</desc>
<path d="M7,9h12c0.5,0,1-0.5,1-1s-0.5-1-1-1H7C6.5,7,6,7.5,6,8S6.5,9,7,9z"/>
<path d="M19,17H7c-0.5,0-1,0.5-1,1s0.5,1,1,1h12c0.5,0,1-0.5,1-1S19.5,17,19,17z"/>
<path d="M10,12c-0.5,0-1,0.5-1,1s0.5,1,1,1h6c0.5,0,1-0.5,1-1s-0.5-1-1-1H10z"/>
</symbol>
</svg>
<svg fill="red">
<use xlink:href="#svg-test"/>
</svg>
<svg fill="blue">
<use xlink:href="#svg-test"/>
</svg>
如何更改图标中的多个颜色
根据上面描述知道,如果安装上面的方式,那能够更改的只有图标中的一种颜色。当然也是可以设置多个颜色。这里使用到css的自定义属性
需要对symbol里面的图标进行更改,将图形的颜色设置为fill: var(--*[, default])的形式。
<symbol id="icon-flag" width="150" height="100" viewBox="0 0 3 2">
<rect width="1" height="2" x="0" style="fill: var(--color0, #008d46)" />
<rect width="1" height="2" x="1" style="fill: var(--color1, #fff)"/>
<rect width="1" height="2" x="2" style="fill: var(--color2, #d2232c)"/>
</symbol>
定义css样式
.flag-belgium {
--color0: #201b18;
--color1: #f1ee3d;
--color2: #dc352f;
}
<svg class="icon">
<use xlink:href="#icon-flag"/>
</svg>
<svg class="icon flag-belgium">
<use xlink:href="#icon-flag"/>
</svg>