# 2019年是时候使用svg-sprite作为网站icon图标的主流了!!!

3,306 阅读5分钟

·序言

为什么选择svg 作为网站的图标系统首选格式?

1.可伸缩矢量图形,图像在放大或改变尺寸的情况下其图形质量不会有所损失;

2.是万维网联盟的标准,是 W3C 推荐标准


1.什么是SVG?

度娘描述: 可缩放矢量图形是基于可扩展标记语言标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式。它由万维网联盟制定,是一个开放标准。

svg英文全称为( Scalable Vector Graphics)

简单的理解,它是图形的另一种格式,和常见的图片格式.png、.jpg、.gif等是一类。


2.SVG 的历史和优势

SVG发展历程

  • 年9月4日,发布SVG 1.0
  • 2003年1月4日,发布SVG 1.1
  • 2003年1月14日,推出SVG移动子版本:SVG Tiny和SVG Basic
  • 2008年12月22日,发布SVG Tiny 1.2
  • 2011年8月16日,发布SVG 1.1(第2版),成为W3C目前推荐的标准
  • W3C目前仍正在研究制定SVG 2

与其他图像格式相比,使用 SVG 的优势在于:

  • SVG 可被非常多的工具读取和修改(比如记事本)
  • SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
  • SVG 是可伸缩的
  • SVG 图像可在任何的分辨率下被高质量地打印
  • SVG 可在图像质量不下降的情况下被放大
  • SVG 图像中的文本是可选的,同时也是可搜索的(很适合制作地图)
  • SVG 可以与 Java 技术一起运行
  • SVG 是开放的标准
  • SVG 文件是纯粹的 XML

3.svg浏览器兼容性问题?

一图胜千言 足够胜任icon系统了


4.svg VS传统图片格式有什么不同呢?

  1. 兼容现有图片能力前提还支持矢量

    SVG提供的功能集涵盖了嵌套转换、裁剪路径、Alpha通道、滤镜效果等能力,它还具备了传统图片没有的矢量功能,在任何高清设备都很高清。

  2. 可读性好,有利于SEO与无障碍

    由于SVG采用的是XML语法,图形的里面的文本内容可以直接被浏览器,搜索引擎SEO和无障碍读屏软件读取,具体用法如下代码设置title与desc标签即可

5.svg VS iconfont图标字体?

SVG iconfont
放大不模糊,无锯齿 浏览器认为它是文本,图标是反锯齿的。可能导致图标是预期的那样尖锐。
能控制图标的各个部分,使用SVG特定的CSS属性,多色图标 通过CSS 控制大小(通过font-sizecolor,阴影,旋转等。
SVG只是它的大小 通过伪元素插入,而这取决于line-heightvertical-alignletter-spacingword-spacing,怎样的字体字形设计(它自然有它周围的空间吗?它有字距信息?)。然后伪元素display类型会影响这些属性是否有效。
浏览器支持SVG,拦截者不关心SVG 广告拦截器提供完全阻止自定义字体。部分浏览器会阻止图标字体的加载,导致网站显示不出来
语义化,图标是小图像。语义上<svg>写着“我是一个形象。” 无语义

Web自1989年到2019年也算是走过了30年的历程,Web上图标的使用也经历了相应的发展:

  1. 最早通过img标签来引用图标(每个图标一个文件)
  2. 为了节省请求,提出了Sprites的概念,即将多个图标合并在一起,使用一个图片文件,借助background相关的属性来实现图标
  3. 图片毕竟是位图,面对多种设备终端,或者说更易于控制图标颜色和大小,开始在使用Icon Font来制作Web图标
  4. 当然,字体图标是解决了不少问题,但每次针对不同的图标的使用,需要自定义字体,也要加载相应的字体文件,相应的也带了一定的问题,比如说跨域问题,字体加载问题
  5. 随着SVG的支持力度越来越强,大家开始在思考SVG,使用SVG来制作图标。该技术能解决我们前面碰到的大部分问题,特别是在而对众多终端设备的时候,它的优势越发明显
  6. SVG和img有点类似,我们也可以借助标签和标签,将所有的SVG图标拼接在一起,有点类似于Sprites的技术,只不过在此称为SVG Sprites
  7. SVG的图标还有一优势,我们可以在CSS中直接通过代码来控制图标的颜色

svg 优化工具 github.com/svg/svgo

从矢量工具导出的SVG文件通常包含大量不必要的数据,例如编辑器元数据,注释,隐藏元素以及可以安全删除而不影响SVG渲染结果的其他内容。

安装工具之前 必须先安装node.js

www.npmjs.com/package/svg…

npm install -g svgo
svgo  xxx.svg

svg-sprite 工程化构建

Gulp配置如下;其他工程化构建工具有类似的工具。

const gulp = require('gulp');
const path = require('path');
const svgmin = require('gulp-svgmin')
const svgstore = require('gulp-svgstore');
const cheerio = require('gulp-cheerio');


gulp.task(`svg-sprite`, function () {
  return gulp
      .src(`./assets/src/images/svg/**/*.svg`)
      .pipe(cheerio({
          run: function ($) {
              $('[class]').removeAttr('class');
          },
          parserOptions: { xmlMode: true }
      }))
      .pipe(svgmin(function (file) {
          var prefix = path.basename(file.relative, path.extname(file.relative));
          return {
              plugins: [{
                  cleanupIDs: {
                      prefix: prefix + '-',
                      minify: true
                  }
              }]
          }
      }))
      .pipe(rename({prefix: 'icon-'}))
      .pipe(svgstore())
      .pipe(rename({prefix: 'icon-'}))
      .pipe(gulp.dest(`./assets/dist/images/svg`))
})

使用方式

.icon-svg-pricing {
  font-size: 24px;
  fill: none;
  stroke: #7a8598;
  width: 1em;
  height: 1em;
}
// 可以根据css来控制一些样式或动画的改变
<svg class="icon-svg-pricing">
	<use xlink:href="./assets/dist/images/svg/icon-svg-sprite.svg#icon-miniapp_live"></use>
</svg>

为兼容IE浏览器,引入相关svg兼容库svg4everybody

<script src="/path/to/svg4everybody.js"></script>
<script>svg4everybody(); // run it now or whenever you are ready</script>