将SVG输出直接放置在页面代码中,我可以像这样简单地用CSS修改填充颜色:

 polygon.mystar {
    fill: blue;
}​

circle.mycircle {
    fill: green;
}
 


这很好用,但是我正在寻找一种方法,当它用作Background-IMAGE时,修改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>
 


评论

我经常用道具打我的答案。您应该考虑将其更改为可接受的答案,这样就不会错过它。

#1 楼

一种方法是从某种服务器端机制为svg提供服务。
只需创建一个资源服务器端,即可根据GET参数输出svg,然后将其提供给特定的url。

那么您只需在CSS中使用该url。

由于作为背景img,它不是DOM的一部分,因此您无法对其进行操作。
另一种可能性是要定期使用它,以常规方式将其嵌入页面中,但要绝对定位,使其完全占据页面的宽度和高度,然后使用z-index css属性将其置于页面上所有其他DOM元素的后面。

评论


不要忘记您是否从服务器端脚本提供SVG,以确保您还发送了正确的MIME标头。在PHP中,将是:<?php header('Content-type:image / svg + xml'); ?>

–轻微故障
2014年8月21日在10:53



您可以使用svg图像作为蒙版,并操纵元素的背景色。这将与更改填充具有相同的效果。 (提供详细答案)

–已嫁
2015年8月3日在23:32



截至2012年,这个答案很棒,但是一段时间以来,所有浏览器都支持CSS掩码和/或过滤器。我建议现在阅读此书的任何人都在下面查看widged的答案中的链接,或者只是跳到此处的CSS Masks,这是一个非常简单的解决方案-请注意,该规则仍需要2个版本,其中一个带有-webkit-前缀时间。对于Microsoft Edge,当前支持CSS筛选器,但尚不支持掩码。

– joelhardi
17年7月4日在17:09

如今,有许多解决方案可以工作,我同意这个答案不再反映当前的可能性状态。

– David Neto
18/12/20在23:15



#2 楼

我需要类似的东西,并希望坚持使用CSS。以下是LESS和SCSS mixin以及可以帮助您的纯CSS。不幸的是,它对浏览器的支持有些松懈。有关浏览器支持的详细信息,请参见下文。

最少的混合:

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




较少使用:

 .element-color(#fff);
 





SCSS mixin:

 @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文件中的更多信息。它还提到了浏览器兼容性,这对于可行的选择来说太小了。

评论


尽管有一些开销,但是由于我必须对所有svg项进行硬编码,因此我认为这是一段时间以来的最佳解决方案。谢谢

–阿德里亚诺·罗莎(Adriano Rosa)
2015年10月19日15:16

如果要以这种方式使用,则需要使用CSS预处理程序,例如Sass或Less。如果您不使用它,则只需为每种颜色使用该背景图像行

–友好代码
16-4-29在18:03



请注意,您必须为十六进制颜色输入#字符,以使其在Firefox中起作用。因此,类似于 的内容将变为

– Swen
16年5月11日在12:17



甜蜜的方法。您是否需要像这样将svg硬编码为背景图像?您不能以某种方式链接到它吗?

– luke
16年7月29日在19:23

我发现此站点有助于为您提供可供使用的完美编码URL:yoksel.github.io/url-encoder-只需将SVG代码复制到其中,然后复制返回的CSS :-)

–友好代码
2月11日,11:07



#3 楼

您可以使用CSS遮罩,并通过'mask'属性创建应用于元素的遮罩。

.icon {
    background-color: red;
    -webkit-mask-image: url(icon.svg);
    mask-image: url(icon.svg);
}


有关更多信息,请参见这篇出色的文章:https: //codepen.io/noahblon/post/coloring-svgs-in-css-background-images

评论


这很好,但是当将其应用于输入字段中的图标时,所有输入文本都将被隐藏。

–理由
18年2月12日在14:54

IE不支援

–贾里姆
18 Mar 17 '18 at 8:11

超级酷的答案,但您不能再在悬停或类似内容中使用背景色

–保罗·克鲁格(Paul Kruger)
18年8月8日在11:21

似乎根本就不支持此功能-太多的用户无法看到它,以使其在2018年底才可行。caniuse.com/#feat=css-masks

–克里斯·莫斯基尼(Chris Moschini)
18年11月28日在16:27

2019年夏季:这个星球上有94%的浏览器支持“ mask-image”或“ -webkit-mask-image”样式

–德米特里·库拉因(Dzmitry Kulahin)
19年7月15日在14:09

#4 楼

另一方法是使用掩模。然后,您可以更改蒙版元素的背景颜色。这与更改svg的填充属性具有相同的效果。

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(不是我自己的)。它提出了多种方法(不限于遮罩)。

评论


需要注意的一件事是浏览器支持。我相信IE(和往常一样)在此方面落后。

–马修·约翰逊(Matthew Johnson)
16年1月12日在16:01

不幸的是,IE和Edge都不支持遮罩:caniuse.com/#search=mask

– alpipego
16 Mar 30 '16 at 8:09

在Chrome中也无法为我工作。编辑:哦nvm ...我没有启用自动前缀。我以为供应商应该停止使用前缀?!

– mpen
17年1月30日在17:25



适用于最新的Chrome和Firefox

–tic
19年3月14日在15:20

#5 楼

Sass有可能!
您唯一要做的就是对svg代码进行url编码。这可以通过Sass中的辅助功能实现。我为此做了一个代码笔。看看这个:

http://codepen.io/philippkuehn/pen/zGEjxB

// choose a color

$icon-color: #F84830;


// functions to urlencode the svg string

@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 url-encode($string) {
  $map: (
    "%": "%25",
    "<": "%3C",
    ">": "%3E",
    " ": "%20",
    "!": "%21",
    "*": "%2A",
    "'": "%27",
    '"': "%22",
    "(": "%28",
    ")": "%29",
    ";": "%3B",
    ":": "%3A",
    "@": "%40",
    "&": "%26",
    "=": "%3D",
    "+": "%2B",
    "$": "%24",
    ",": "%2C",
    "/": "%2F",
    "?": "%3F",
    "#": "%23",
    "[": "%5B",
    "]": "%5D"
  );
  $new: $string;
  @each $search, $replace in $map {
    $new: str-replace($new, $search, $replace);
  }
  @return $new;
}

@function inline-svg($string) {
  @return url('data:image/svg+xml;utf8,#{url-encode($string)}');
}


// icon styles
// note the fill="' + $icon-color + '"

.icon {
  display: inline-block;
  width: 50px;
  height: 50px;
  background: inline-svg('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
   viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">
<path fill="' + $icon-color + '" d="M18.7,10.1c-0.6,0.7-1,1.6-0.9,2.6c0,0.7-0.6,0.8-0.9,0.3c-1.1-2.1-0.4-5.1,0.7-7.2c0.2-0.4,0-0.8-0.5-0.7
  c-5.8,0.8-9,6.4-6.4,12c0.1,0.3-0.2,0.6-0.5,0.5c-0.6-0.3-1.1-0.7-1.6-1.3c-0.2-0.3-0.4-0.5-0.6-0.8c-0.2-0.4-0.7-0.3-0.8,0.3
  c-0.5,2.5,0.3,5.3,2.1,7.1c4.4,4.5,13.9,1.7,13.4-5.1c-0.2-2.9-3.2-4.2-3.3-7.1C19.6,10,19.1,9.6,18.7,10.1z"/>
</svg>');
}


评论


效果很好。唯一的问题:在IE10中,图标太小了(我认为是给定大小的10%。

– Henning Fischer
16年5月24日15:05

#6 楼

使用棕褐色滤镜以及色相旋转,亮度和饱和度来创建我们想要的任何颜色。

.colorize-pink {
  filter: brightness(0.5) sepia(1) hue-rotate(-70deg) saturate(5);
}


https://css-tricks.com/solved- with-css-colorizing-svg-backgrounds /

评论


使用此CSS过滤器生成器:codepen.io/sosuke/pen/Pjoqqp

– djibe
11月3日,22:09

是的,这应该是答案。请遵循@djibe中的CSS过滤器生成器说明。

– A.J.埃尔南德斯
11月7日,1:12

#7 楼

 .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);
}


codeben文章和演示

评论


此方法会将过滤器应用于整个对象,包括子对象。

– Krzysztof Antoniak
17年6月14日在13:28

#8 楼

现在,您可以像这样在客户端实现此目标:

var green = '3CB54A';
var red = 'ED1F24';
var 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="#'+green+'" 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="#'+red+'" cx="202.028" cy="58.342" r="12.26"/></svg>';      
var encoded = window.btoa(svg);
document.body.style.background = "url(data:image/svg+xml;base64,"+encoded+")";


在这里拨弄!

评论


您应该避免将Base64用于SVG,因为这是不必要的,它会使文件更大,甚至阻止GZIP有效地压缩那些代码块。

– inta
17年1月17日在16:53

这种编码发生在客户端,可能只是为了彻底转义...

– Diachedelic
17年11月6日在6:37

不用说您可以使用JS做任何事情。重点是避免JS。

– MarsAndBack
1月16日15:16

#9 楼

将您的svg下载为文本。

使用javascript修改svg文本以更改绘画/描边/填充颜色[s]。

然后将修改后的svg字符串内联嵌入到您的如此处所述的CSS。

#10 楼

您可以将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 />元素没有现有的填充颜色,并且未设置width或height属性。由于输入是在SCSS文档中进行硬编码的,因此强制实施这些约束非常容易。

不必担心代码重复。 gzip压缩使差异微不足道。

评论


重复代码是一种代码味道,因此建议人们在您的示例情况下不要担心重复代码不是一个好主意,但是说我看不到您的代码在哪里重复?我认为,如果您完全删除评论,那会更好。

–编程教授
1月7日17:09

#11 楼

您可以为此创建自己的SCSS函数。将以下内容添加到您的config.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文件保持整洁!

评论


这是来自github问题。只是在这里引用它,以防有人想要阅读那里的讨论

– MMachinegun
15-10-26在10:57

#12 楼

在某些(非常特定的)情况下,可以通过使用过滤器来实现。例如,您可以使用filter: hue-rotate(45deg);将色相旋转45度,将蓝色SVG图像更改为紫色。浏览器支持很小,但仍然是一种有趣的技术。

演示

#13 楼

对于单色背景,您可以使用带遮罩的svg,其中应显示背景颜色



#14 楼

但是,在此显示晚了,但是,如果您能够直接编辑SVG代码,则能够向SVG多边形添加填充颜色,例如,以下svg呈现红色,而不是默认的黑色。我尚未在Chrome外部进行测试:

<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="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve">
    <polygon 


        fill="red"


        fill-rule="evenodd" clip-rule="evenodd" points="452.5,233.85 452.5,264.55 110.15,264.2 250.05,390.3 229.3,413.35 
47.5,250.7 229.3,86.7 250.05,109.75 112.5,233.5 "/>
</svg>


#15 楼

这是我最喜欢的方法,但是您的浏览器支持必须非常先进。使用mask属性,您可以创建应用于元素的遮罩。遮罩不透明或实心的任何地方,下面的图像都会显示出来。在透明的地方,基础图像被掩盖或隐藏。 CSS遮罩图像的语法与background-image相似。请查看代码笔mask

#16 楼

大量的IF,但是如果您的prebase64编码的SVG开始:

<svg fill="#000000


,那么base64编码的字符串将开始: />
如果预编码的字符串开始:

PHN2ZyBmaWxsPSIjMDAwMDAw


,则此编码为:

<svg fill="#bfa76e

<两种编码的字符串都以相同的开头:

PHN2ZyBmaWxsPSIjYmZhNzZl


base64编码的怪癖是每3个输入字符变为4个输出字符。像这样从SVG开始,然后6个字符的十六进制填充颜色完全在编码块“边界”上开始。
因此,您可以轻松地进行跨浏览器JS替换:

PHN2ZyBmaWxsPSIj


但是上面的tnt-rox答案是前进的方法。

评论


似乎公众不喜欢使用base64

–启示
7月6日17:27