将SVG输出直接内联到页面代码中,我可以简单地用CSS修改填充颜色,如下所示:

polygon.mystar {
    fill: blue;
}​

circle.mycircle {
    fill: green;
}

这工作得很好,但是我正在寻找一种方法来修改SVG的“填充”属性,当它作为背景-图像时。

html {      
    background-image: url(../img/bg.svg);
}

我现在怎么改变颜色?这可能吗?

作为参考,以下是我的外部SVG文件的内容:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve">
<polygon class="mystar" fill="#3CB54A" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679 
    118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/>
<circle class="mycircle" fill="#ED1F24" cx="202.028" cy="58.342" r="12.26"/>
</svg>

当前回答

您可以为此创建自己的SCSS函数。将以下内容添加到配置中。rb文件。

require 'sass'
require 'cgi'

module Sass::Script::Functions

  def inline_svg_image(path, fill)
    real_path = File.join(Compass.configuration.images_path, path.value)
    svg = data(real_path)
    svg.gsub! '{color}', fill.value
    encoded_svg = CGI::escape(svg).gsub('+', '%20')
    data_url = "url('data:image/svg+xml;charset=utf-8," + encoded_svg + "')"
    Sass::Script::String.new(data_url)
  end

private

  def data(real_path)
    if File.readable?(real_path)
      File.open(real_path, "rb") {|io| io.read}
    else
      raise Compass::Error, "File not found or cannot be read: #{real_path}"
    end
  end

end

然后你可以在你的CSS中使用它:

.icon {
  background-image: inline-svg-image('icons/icon.svg', '#555');
}

您需要编辑SVG文件,并将标记中的任何填充属性替换为fill="{color}"

图标路径总是相对于相同配置中的images_dir参数。rb文件。

类似于其他一些解决方案,但这是非常干净的,并保持您的SCSS文件整洁!

其他回答

我需要一些类似的东西,并想坚持使用CSS。这里有LESS和SCSS mixins以及普通的CSS,可以帮助你做到这一点。不幸的是,它的浏览器支持有点松懈。有关浏览器支持的详细信息,请参见下面。

更少的混合:

.element-color(@color) {
  background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="@{color}" ... /></g></svg>');
}

更少的使用方法:

.element-color(#fff);

SCSS混合:

@mixin element-color($color) {
  background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="#{$color}" ... /></g></svg>');
}

SCSS用法:

@include element-color(#fff);

CSS:

// color: red
background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="red" ... /></g></svg>');

这里有更多关于将完整的SVG代码嵌入到CSS文件中的信息。它还提到浏览器兼容性有点太小,这是一个可行的选择。

 .icon { 
  width: 48px;
  height: 48px;
  display: inline-block;
  background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/heart.svg) no-repeat 50% 50%; 
  background-size: cover;
}

.icon-orange { 
  -webkit-filter: hue-rotate(40deg) saturate(0.5) brightness(390%) saturate(4); 
  filter: hue-rotate(40deg) saturate(0.5) brightness(390%) saturate(4); 
}

.icon-yellow {
  -webkit-filter: hue-rotate(70deg) saturate(100);
  filter: hue-rotate(70deg) saturate(100);
}

代码本文章和演示

还有一种方法是使用蒙版。然后更改蒙面元素的背景颜色。这与更改svg的fill属性具有相同的效果。

HTML:

<glyph class="star"/>
<glyph class="heart" />
<glyph class="heart" style="background-color: green"/>
<glyph class="heart" style="background-color: blue"/>

CSS:

glyph {
    display: inline-block;
    width:  24px;
    height: 24px;
}

glyph.star {
  -webkit-mask: url(star.svg) no-repeat 100% 100%;
  mask: url(star.svg) no-repeat 100% 100%;
  -webkit-mask-size: cover;
  mask-size: cover;
  background-color: yellow;
}

glyph.heart {
  -webkit-mask: url(heart.svg) no-repeat 100% 100%;
  mask: url(heart.svg) no-repeat 100% 100%;
  -webkit-mask-size: cover;
  mask-size: cover;
  background-color: red;
}

你可以在这里找到完整的教程:http://codepen.io/noahblon/blog/coloring-svgs-in-css-background-images(不是我自己的)。它提出了多种方法(不限于掩码)。

实现这一点的一种方法是从某种服务器端机制提供svg。 只需创建一个资源服务器端,根据GET参数输出svg,并在某个url上提供它。

然后在css中使用这个url。

因为作为一个背景img,它不是DOM的一部分,你不能操作它。 另一种可能是定期使用它,以正常的方式将它嵌入到页面中,但绝对定位它,使它成为一个页面的全宽和高,然后使用z-index css属性将它放在页面上所有其他DOM元素的后面。

您可以将SVG存储在一个变量中。然后根据需要操作SVG字符串(即设置宽度、高度、颜色等)。然后使用结果来设置背景,例如:

$circle-icon-svg: '<svg xmlns="http://www.w3.org/2000/svg"><circle cx="10" cy="10" r="10" /></svg>';

$icon-color: #f00;
$icon-color-hover: #00f;

@function str-replace($string, $search, $replace: '') {
    $index: str-index($string, $search);

    @if $index {
        @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
    }

    @return $string;
}

@function svg-fill ($svg, $color) {
  @return str-replace($svg, '<svg', '<svg fill="#{$color}"');
}

@function svg-size ($svg, $width, $height) {
  $svg: str-replace($svg, '<svg', '<svg width="#{$width}"');
  $svg: str-replace($svg, '<svg', '<svg height="#{$height}"');

  @return $svg;
}

.icon {
  $icon-svg: svg-size($circle-icon-svg, 20, 20);

  width: 20px; height: 20px; background: url('data:image/svg+xml;utf8,#{svg-fill($icon-svg, $icon-color)}');

  &:hover {
    background: url('data:image/svg+xml;utf8,#{svg-fill($icon-svg, $icon-color-hover)}');
  }
}

我也做了一个演示,http://sassmeister.com/gist/4cf0265c5d0143a9e734。

这段代码对SVG做了一些假设,例如< SVG />元素没有现有的填充颜色,宽度和高度属性都没有设置。由于输入是在SCSS文档中硬编码的,因此执行这些约束非常容易。

不要担心代码复制。Gzip压缩使得这种差异可以忽略不计。