标签引入SVG优于使用独立图像或组合图像(CSSsprite)。SVGvsIconfont写法对比首先看一下Iconfont和SVG图标的用法。来源为阿里iconfont平台。很明显,SVGSprite使用起来没有Iconfont方便。它需要写3行代码,而后者只需要写1行。当然上面不是重点,重点是下面的变色和多色支持变色和多色支持变色1.iconfont可以很方便的通过CSS颜色来改变图标颜色。2、虽然SVGSprite比较麻烦,但是SVGSprite的代码原理如下。//定义符号//使用渲染的DOM结构是这样的:在ShadowDOM中渲染(关于ShadowDOM的知识可以看这篇文章或这篇文章),这样的DOM元素样式是有作用域的,外面的CSS对里面的元素没有影响shadow-root才会生效.如果要改变元素的颜色,需要使用/deep/来穿透添加样式,如下。svg/deep/path{fill:red;}当然,其实只要在父元素上加上fill:red就可以达到同样的效果,里面的元素会继承父元素的样式。PS:/deep/是shadowDOMv0的写法,v1放弃了这种写法,实际上支持v1的shadowDOM,父级的样式可以直接影响shadow-root中的元素。多色支持1.Iconfont不支持多色图标。2.SVGSprite可以使用CSS变量或者shadowDOM来支持多色图标。shadowDOM方法上面已经解释过了。借用别人的文章讲解CSS变量实现多色,如下。但是,使用CSS变量或shadowDOM的兼容性并不好。CSS变量:Edge15+shadowDOM:更糟。兼容性列表3.InlineSVG可以很好地支持多色多色变化。渐变支持Iconfont,SVGSprite不支持渐变。InlineSVG支持渐变色,兼容性好。Renderwithoutjitter使用Iconfont,因为字体文件是异步加载的,所以在字体文件加载前,图标位置会空白,加载完后显示,流程会出现如下图(来自GitHub博客)这样的抖动,而SVGSprite或InlineSVG内联加载不会有这样的抖动。当然Iconfont也可以内联加载,但是需要转成base64和样式表一起加载,转换后的文件大小会变成原来大小的1.3倍左右,这是由base64编码决定的(链接编码知识)。字体转base64的在线工具:https://transfonter.org/尺寸较大这是SVG相对于Iconfont的劣势,如下图。内联SVG的大小与SVGSprite大致相同。开发成本三者的开发成本差不多,但是SVG的两种方式都需要前期进行一些配置,后期开发会容易很多(单页应用)。以vue+vuecli为例,说明InlineSVG的便捷使用。1.配置Webpackloader:{//排除需要转成InlineSVG的目录exclude:[resolve('src/svgicons')],test:/\.(png|jpe?g|gif|svg)(\?.*)?$/,loader:'url-loader',options:{limit:1,name:utils.assetsPath('img/[name].[hash:7].[ext]')}},{//指定InlineSVG的具体目录include:[resolve('src/svgicons')],test:/\.svg$/,use:[//readSVGsource{loader:'raw-loader'},//精简和优化的SVG源代码{loader:'svgo-loader',options:{plugins:[{removeTitle:true},{removeViewBox:false},{removeDimensions:true},//...其他参数]}}]}2.创建SvgIcon.vue组件:
