我们都知道如果把SVG嵌入到html中,可以使用fill来对SVG图片进行颜色填充;如果你使用css中的背景图片来引用SVG图片,那就无法使用fill来对SVG进行颜色填充。那还有其它的方法既要使用背景图片来引用SVG,又要改变它的颜色,这篇文章就来聊聊这个话题。
在CSS背景图片中使用SVG的优点
在CSS背景图片中使用SVG,可以使用css background属性的诸多特性,比如图片尺寸和图片位置等等。可以非常轻松的根据设备的尺寸来控制图片的尺寸,还有一个好处就是可以不用把SVG图片插入到html中,从而保持html的整洁。
在CSS背景图片中使用SVG,有很多的优点,对提高性能也是有很大帮助的。
那在CSS背景图片中使用SVG,有什么方法来改变它的颜色呢?接着看。
CSS mask
使用CSS中mask来改变背景颜色,这个方法简单实用,重要的是现在浏览器对它的支持越来越好。mask属性可以用来根据元素的轮廓来创建一个遮罩,使用遮罩可以只显示指定图片内容的区域,而图片区域以外的则是隐藏的。下面是它的使用方法:
.icon {
background-color: red;
-webkit-mask-image: url(icon.svg);
mask-image: url(icon.svg);
}
下面来看使用mask的实例。为了能自定义icon的颜色,我们使用background-color来定义背景颜色,使用SVG图片来定义遮罩区域,这样图片就能显示前面定义好的背景颜色。因此,我们可以指定任意的颜色来填充SVG。不过,mask这个属性还没有正式成为W3C标准,需要针对不同的浏览器来写,比如webkit内核就需要-webkit这个前缀。

mask还有很多的属性,比如mask-position、mask-repeat和mask-size,它们跟CSS中背景图片的对应属性的使用方法都差不多,也可以像background一样来使用简写语法:
.icon {
background-color: red;
-webkit-mask: url(icon.svg) no-repeat 50% 50%;
mask: url(icon.svg) no-repeat 50% 50%;
}
浏览器对mask的支持也越来越好。可以通过下面的地址来看看各个浏览器对它的支持情况:
CSS filters
CSS filter 这个属性可以像photoshop中的滤镜一样给DOM元素添加滤镜效果。CSS中filter属性还可以通过叠加不同的值来产生不同的效果。
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewbox="0 0 24 24">
<path fill="red" d="M12 21.35l-1.45-1.32c-5.15-4.67-8.55-7.75-8.55-11.53 0-3.08 2.42-5.5 5.5-5.5 1.74 0 3.41.81 4.5 2.09 1.09-1.28 2.76-2.09 4.5-2.09 3.08 0 5.5 2.42 5.5 5.5 0 3.78-3.4 6.86-8.55 11.54l-1.45 1.31z"/>
</svg>
.icon-blue {
-webkit-filter: hue-rotate(220deg) saturate(5);
filter: hue-rotate(220deg) saturate(5);
}
在上面的例子中,使用SVG中的fill属性把icon的颜色填充为红色。通过hue-rotate这个旋转色相的属性旋转色相220度,通过改变色相的角度改变颜色,这样就可以把红色改为蓝色。当然,通过旋转色相来改变颜色并不是非常准确,跟实际的颜色还是会有一点点差距。不过,可以通过给颜色添加一点点饱和度,即saturation这个改变颜色饱和度的filter。在上面的例子中,我增加了一个比较大的饱和度的值,为500%,这样就可以是颜色更加的纯。
在两个filter的作用下,就可以给icon添加不同的颜色。比如下面的这个例子,我通过整合hue-rotate, invert, brightness和saturation这几个不同的filter就创建彩虹色的icon。

当然,你如果想创建灰色的icon,也非常简单,可以使用grayscale这个灰色的filter并且调整brightness的值来实现你想要的灰色的效果。
这种通过filter来调整颜色还不是特别的友好直观。要想实现想要的效果,需要通过反复的调整才能达到。不过,要是以后CSS滤镜能通过调整HSL的值来调整颜色效果,那就比现在方便多了。
CSS filter现在在大部分的浏览器上支持的都比较好,IE在不久之后,也会支持。
Data URL
Chris Coyier在他的Probably Don't Base-64 SVG这篇文章中,建议直接使用SVG XML来使用SVG。当然,要是用这种技术,得借助Sass这种预编译语言来实现,这里我使用了Sass来实现颜色的填充,你也可以自定义自己喜欢的颜色。

这里需要用到SASS中的数组即Sass map这个特性来管理颜色,Sass map可以使用key:value来定义一些参数的调用。利用这个特性,可以把icon的名字定义为key,而把诸如color、stroke-color等属性定义对应icon的value,非常方便灵活。
使用URL编码的形式虽然可以在IE上能正常工作,不过还是有一点点复杂的。
SVG Background Sprite
SVG中的sprite跟CSS中的sprite概念一样,都是把图片合成在一张大的图片里。在CSS中,通过使用background-size和background-position这两个属性来引用你想用的某一张图片。具体到SVG,则有不同的使用方法,比如下面:
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="24"
height="576">
<defs>
<symbol id="heart">
<path d="M12 21.35l-1.45-1.32c-5.15-4.67-8.55-7.75-8.55-11.53 0-3.08 2.42-5.5 5.5-5.5 1.74 0 3.41.81 4.5 2.09 1.09-1.28 2.76-2.09 4.5-2.09 3.08 0 5.5 2.42 5.5 5.5 0 3.78-3.4 6.86-8.55 11.54l-1.45 1.31z"/>
</symbol>
</defs>
<use xlink:href="#heart" x="0" y="0" fill="red" />
<use xlink:href="#heart" x="0" y="24" fill="orange" />
<use xlink:href="#heart" x="0" y="48" fill="yellow" />
<use xlink:href="#heart" x="0" y="72" fill="green" />
<use xlink:href="#heart" x="0" y="96" fill="blue" />
<use xlink:href="#heart" x="0" y="120" fill="indigo" />
<use xlink:href="#heart" x="0" y="144" fill="violet" />
<use xlink:href="#heart" x="0" y="168" fill="cyan" />
<use xlink:href="#heart" x="0" y="192" fill="magenta" />
<use xlink:href="#heart" x="0" y="216" fill="lime" />
<use xlink:href="#heart" x="0" y="240" fill="olive" />
<use xlink:href="#heart" x="0" y="264" fill="maroon" />
<use xlink:href="#heart" x="0" y="288" fill="purple" />
<use xlink:href="#heart" x="0" y="312" fill="#fff" />
<use xlink:href="#heart" x="0" y="336" fill="#e5e5e5" />
<use xlink:href="#heart" x="0" y="360" fill="#ccc" />
<use xlink:href="#heart" x="0" y="384" fill="#b2b2b2" />
<use xlink:href="#heart" x="0" y="408" fill="#999" />
<use xlink:href="#heart" x="0" y="432" fill="#7f7f7f" />
<use xlink:href="#heart" x="0" y="456" fill="#666" />
<use xlink:href="#heart" x="0" y="480" fill="#4c4c4c" />
<use xlink:href="#heart" x="0" y="504" fill="#333" />
<use xlink:href="#heart" x="0" y="528" fill="#191919" />
<use xlink:href="#heart" x="0" y="552" fill="#000" />
</svg>
上面就是一种SVG sprite的使用方法,把需要用到的图片定义在symbol元素中,定义好ID,宽高根据图片每一个图片的宽高来定义,比如上面我使用了24张图片,每一张图片的宽高是24,所以总的sprite宽高是24X576,然后在需要引用图片的地方使用use标签来引用。每一个图片的颜色都可以通过fill属性来改变。

除来上面使用use的方法来适应sprite,也可以像CSS一样使用背景图片的方式来使用sprite,使用Sass的话更方便一些。
这种使用背景图片的方法浏览器支持的非常好,不过由于要针对不同颜色的图片单独创建一个对应颜色图片,所以用起来不是很灵活。
上面就大概介绍一些在CSS背景图片中对SVG图片进行着色的一些方法。可能不是很全面,你还知道哪些方法,欢迎留言一起讨论。
本文主要是从Coloring SVGs in CSS Background Images这篇文章整理而来,有删减,有疏漏或者理解不到位的地方,还请多多指教!