SVG图标的Sprite处理

svg正在越来越广泛的应用在前端领域,由于矢量图缩放对图像质量无损,越来越多的图标、图片都开始使用svg。但svg文件一旦多起来,就需要对这些资源进行集中管理。webpack的svg-loader只是简单的将svg文件替换成了文本内容,增加了bundle文件的体积,灵活性也不高,如果能将svg文件处理成类似于jpg/png图片一样,做成sprite就好了。而这正是svg-sprite-loader要做的事情。

viewBox

在svg文件中,可以创建若干个view,view包含一个名为viewBox的属性,viewBox允许我们定义一个矩形区域,通过四个参数 left, top, width和height,可以通过设置id来对view进行标示。
当定义view之后,在引入svg文件时,就可以指定显示某个view,如下所示

<img src="sprite.svg#svgView(viewBox(0, 0, 32, 32))" alt="">

.icon-clock {
  background: url(sprite.svg#icon-clock-view) no-repeat;
}

这样一来,就可以在单个svg文件中包含多个view,而显示时根据需要显示特定的局部内容,完成sprite的需求。

Svg Stack

svg还能通过target伪类对view进行堆叠处理,原理很简单,就是在svg文件中定义了多个图形元素时,可以通过css设置,将所有的图形元素g设置为不显示,而通过伪类:target将当前选中的元素display指设置为inline予以展示。

  <style>
    g {
      display: none;
    }
    g:target {
      display: inline;
    }
  </style>

举个例子,假设有3个3232的图标,在svg文件中,可以通过定义3个3232的图像来表示这3个图标,同时默认这3个图标由于样式作用,默认都是不可见的,而通过id引用到某个图像时,target伪类会使得该图标display值发生变化,从而变得可见。这样一来,就不需要3296或者9632的区域来存放这3个图标了,而是将它们堆叠在32*32的区域即可。

svg-sprite-loader

通过webpack的svg-sprite-loader,能够帮我们自动管理svg资源,将它们做成一个sprite文件进行使用,更多用法参见https://github.com/kisenka/svg-sprite-loader

参考文献

  1. https://css-tricks.com/svg-fragment-identifiers-work/#article-header-id-4
  2. https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
  3. https://github.com/kisenka/svg-sprite-loader
Show Comments

Get the latest posts delivered right to your inbox.