首页 文章

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

提问于
浏览
166

将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>

14 回答

  • 9

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

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

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

  • 11

    我需要类似的东西,并希望坚持使用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:

    @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>');
    

    Here is more info将完整的SVG代码嵌入到CSS文件中 . 它还提到了浏览器兼容性,这对于一个可行的选择而言有点小 .

  • -2

    另一种方法是使用面罩 . 然后,您可以更改蒙版元素的背景颜色 . 这与更改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(不是我自己的) . 它提出了各种方法(不限于掩模) .

  • 29

    您可以使用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

  • 1

    这可能与萨斯!你唯一要做的就是对你的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>');
    }
    
  • 1

    下载您的svg文本 .

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

    然后将修改后的svg字符串嵌入到您的css中,如here所述 .

  • 4

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

    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+")";
    

    Fiddle here!

  • 101

    您可以将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压缩使得差异可以忽略不计 .

  • 56

    您可以为此创建自己的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 =“”替换标记中的所有填充属性

    图标路径始终相对于同一config.rb文件中的images_dir参数 .

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

  • 39
    .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 article and demo

  • 3

    在这里显示的时间晚了,但是,如果你能够直接编辑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>
    
  • 3

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

    Demo

  • -1

    这是我最喜欢的方法,但您的浏览器支持必须非常进步 . 使用mask属性可以创建应用于元素的蒙版 . 在任何地方,掩模都是不透明的,或者是实体的,底层图像显示出来 . 在透明的地方,底层图像被掩盖或隐藏 . CSS mask-image的语法类似于background-image . look at the codepen mask

  • 8

    很多IF,但如果您的pre base64编码SVG启动:

    <svg fill="#000000
    

    然后base64编码的字符串将启动:

    PHN2ZyBmaWxsPSIjMDAwMDAw
    

    如果预编码的字符串开始:

    <svg fill="#bfa76e
    

    然后这编码为:

    PHN2ZyBmaWxsPSIjYmZhNzZl
    

    两个编码的字符串都是相同的:

    PHN2ZyBmaWxsPSIj
    

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

    output = input.replace(/MDAwMDAw/, "YmZhNzZl");
    

    但上面的tnt-rox回答是前进的方法 .

相关问题