在作为Background-Image提供时修改SVG填充颜色

Joe*_*Joe 231 html css html5 svg css3

将SVG输出直接与页面代码一起放置我可以使用CSS简单地修改填充颜色,如下所示:

polygon.mystar {
    fill: blue;
}?

circle.mycircle {
    fill: green;
}
Run Code Online (Sandbox Code Playgroud)

这很好用,但是我正在寻找一种方法来修改SVG的"填充"属性,当它被用作背景图像时.

html {      
    background-image: url(../img/bg.svg);
}
Run Code Online (Sandbox Code Playgroud)

我现在该如何改变颜色?它甚至可能吗?

作为参考,这是我的外部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>
Run Code Online (Sandbox Code Playgroud)

Rya*_*yan 132

我需要类似的东西,并希望坚持使用CSS.这里有LESS和SCSS mixins以及可以帮助你解决这个问题的简单CSS.不幸的是,它的浏览器支持有点松懈.有关浏览器支持的详细信息,请参阅

混合:

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

使用率较低:

.element-color(#fff);
Run Code Online (Sandbox Code Playgroud)

SCSS mixin:

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

SCSS用法:

@include element-color(#fff);
Run Code Online (Sandbox Code Playgroud)

CSS:

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

以下是有关将完整SVG代码嵌入CSS文件的更多信息.它还提到了浏览器兼容性,这对于一个可行的选择而言有点小.

  • 请注意,您必须对您的十六进制颜色的`#`字符进行urlencode,以使其在Firefox中正常工作.所以像`<svg fill ="#ffffff"...> </ svg>`变成`<svg fill ="%23ffffff"...> </ svg>`. (25认同)
  • 我走了这条路,却发现它在生产中被任何具有良好安全监听器的反向代理阻止,如下所述:/sf/answers/4354925711/。这很容易受到 XSS 攻击。 (3认同)
  • 甜蜜的方法。你是否必须像这样将 svg 硬编码到背景图像中?你不能以某种方式链接到它吗? (2认同)
  • 我发现这个网站可以为您提供完美编码的可供使用的 URL:https://yoksel.github.io/url-encoder/ - 只需将 SVG 代码复制到其中并复制返回的 CSS :-) (2认同)

ton*_*o.j 71

一种方法是从服务器端机制服务你的svg.只需创建一个资源服务器端,根据GET参数输出您的svg,然后在某个URL上提供它.

然后你只需在你的CSS中使用该URL.

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

  • 不要忘记,如果您从服务器端脚本提供SVG,请确保您还发送正确的[MIME标题](http://en.wikipedia.org/wiki/MIME#MIME_headers).在PHP中,这将是:`<?php header('Content-type:image/svg + xml'); ?>` (7认同)
  • 截至2012年,这个答案很棒,但是一段时间以来,所有浏览器都支持CSS掩码和/或过滤器。我建议现在阅读此书的人查看下面widged的答案中的链接,或者直接跳到[此处的CSS掩码](https://codepen.io/noahblon/post/coloring-svgs-in-css-background-images#css -masks-1),这是一个非常简单的解决方案-请注意,它仍然[需要2个版本的规则,一个带有-webkit-前缀的规则](http://caniuse.com/#feat=css-masks)现在的时间。对于Microsoft Edge,当前支持CSS筛选器,但尚不支持掩码。 (7认同)
  • 您可以使用svg图像作为蒙版并操纵元素的背景颜色.这与更改填充效果相同.(提供详细答案) (4认同)
  • 现在提供了许多解决方案,我同意这个答案不再反映当前的可能性状态。 (4认同)

Ade*_*del 70

您可以使用CSS掩码,使用'mask'属性,可以创建应用于元素的掩码.

.icon {
    background-color: red;
    -webkit-mask-image: url(icon.svg);
    mask-image: url(icon.svg);
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅此文章:https://codepen.io/noahblon/post/coloring-svgs-in-css-background-images

  • IE不支持 (11认同)
  • 这个答案最近得到了更多的关注,所以我想我应该指出它不是背景图像。这掩盖了整个元素,包括它的内容。如果我想将一个元素专用于图像,我可以使用带有填充集的普通 SVG。屏蔽在某些情况下很有用,但我认为它并不真正有资格作为这个特定问题的答案。 (7认同)
  • 2019年夏季:这个星球上有94%的浏览器支持“ mask-image”或“ -webkit-mask-image”样式 (3认同)
  • 这很好,但是当将其应用于输入字段中的图标时,所有输入文本都将被隐藏。 (2认同)
  • @cronoklee - 虽然你在技术上是正确的,但“mask-image”有效*可以*用于创建“背景图像”。要在不需要遮罩时在元素 A 上使用此方法,请创建一个与元素 A 具有相同位置和尺寸的元素 B(使用您喜欢的任何方法),并将“遮罩图像”应用​​于元素 B。 (2认同)

wid*_*ged 52

另一种方法是使用面罩.然后,您可以更改蒙版元素的背景颜色.这与更改svg的fill属性具有相同的效果.

HTML:

<glyph class="star"/>
<glyph class="heart" />
<glyph class="heart" style="background-color: green"/>
<glyph class="heart" style="background-color: blue"/>
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 有一点需要注意的是浏览器支持.我相信IE(像往常一样)落后于此. (11认同)
  • 不幸的是,IE和Edge都不支持`mask`:http://caniuse.com/#search=mask (9认同)
  • @alpipego 更新![Edge 在 2017 年底添加了对“mask-image”的支持](https://caniuse.com/?search=mask-image)。 (2认同)

小智 26

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

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

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

  • 使用此 CSS 过滤器生成器:https://codepen.io/sosuke/pen/Pjoqqp (10认同)

Phi*_*ühn 16

这可能与萨斯!你唯一要做的就是对你的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>');
}
Run Code Online (Sandbox Code Playgroud)

  • 这非常好.唯一的问题:在IE10中,图标太小(我认为给定尺寸的10%). (2认同)

Ant*_*ida 13

如果您尝试直接在 CSS 上使用 SVG,url()如下所示;

a:before {
  content: url('data:image/svg+xml; utf8, <svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 451 451"><path d="M345.441,2...
Run Code Online (Sandbox Code Playgroud)

您应该将其编码#%23,否则它将无法工作。

<svg fill="%23FFF" ...
Run Code Online (Sandbox Code Playgroud)


jed*_*ikb 9

下载您的svg作为文本.

使用javascript修改您的svg文本以更改绘画/笔触/填充颜色[s].

如上所述然后嵌入SVG修改字符串内嵌到你的CSS 这里.


tnt*_*rox 9

现在您可以在客户端实现此目的:

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+")";
Run Code Online (Sandbox Code Playgroud)

小提琴!


Elb*_*baz 9

 .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);
}
Run Code Online (Sandbox Code Playgroud)

Codeben文章和演示

  • 此方法会将过滤器应用于整个对象,包括子对象。 (2认同)

小智 9

由于尽管年龄很大,但谷歌上仍然出现了这个问题,所以在查看了这里的选项后,我想我不妨给出一个我在 2022 年遥远的未来使用的解决方案。

这实际上只是之前的掩模解决方案,但是在伪元素上。

.icon {
    height: 1.5rem;
    width: 1.5rem;
}
.icon::before {
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    mask-repeat: no-repeat;
    mask-position: center;
    mask-size: contain;
    mask-image: url("path/to/svg/icon.svg");
    -webkit-mask-repeat: no-repeat;
    -webkit-mask-position: center;
    -webkit-mask-size: contain;
    -webkit-mask-image: url("path/to/svg/icon.svg");
}
Run Code Online (Sandbox Code Playgroud)

这适用于当今所有主要浏览器,尽管显然您不能使用它来获得具有多种颜色的 SVG。如果网站不允许您内联注入它们,或者您不喜欢做字体图标等,这就是业务成本。


Gaj*_*jus 7

您可以将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)}');
  }
}
Run Code Online (Sandbox Code Playgroud)

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

此代码对SVG做了一些假设,例如,该<svg />元素没有现有的填充颜色,并且既没有设置宽度或高度属性.由于输入在SCSS文档中是硬编码的,因此很容易实施这些约束.

不要担心代码重复.压缩使差异可以忽略不计.


ari*_*had 6

您可以使用亮度滤镜,任何大于 1 的值都会使元素更亮,任何小于 1 的值都会使其更暗。因此,我们可以使那些亮的 SVG\xe2\x80\x99s 变暗,反之亦然,例如,这将使 svg 变暗:

\n
filter: brightness(0);\n
Run Code Online (Sandbox Code Playgroud)\n

为了改变颜色而不仅仅是亮度级别,我们可以使用棕褐色滤镜以及色调旋转、亮度,例如:

\n
.colorize-blue {\n  filter: brightness(0.5) sepia(1) hue-rotate(140deg) saturate(6);\n}\n
Run Code Online (Sandbox Code Playgroud)\n


fdr*_*drv 6

如果您想以简单的方式从白色切换为黑色或类似的方式,请尝试以下操作:

filter: invert(100%);
Run Code Online (Sandbox Code Playgroud)