Modify SVG fill color when being served as Background-Image

后端 未结 16 1014
再見小時候
再見小時候 2020-11-22 06:31

Placing the SVG output directly inline with the page code I am able to simply modify fill colors with CSS like so:

po         


        
相关标签:
16条回答
  • 2020-11-22 06:59

    Now you can achieve this on the client side like this:

    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!

    0 讨论(0)
  • 2020-11-22 07:00

    One way to do this is to serve your svg from some server side mechanism. Simply create a resource server side that outputs your svg according to GET parameters, and you serve it on a certain url.

    Then you just use that url in your css.

    Because as a background img, it isn't part of the DOM and you can't manipulate it. Another possibility would be to use it regularly, embed it in a page in a normal way, but position it absolutely, make it full width & height of a page and then use z-index css property to put it behind all the other DOM elements on a page.

    0 讨论(0)
  • 2020-11-22 07:01

    for monochrome background you could use a svg with a mask, where the background color should be displayed

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" preserveAspectRatio="xMidYMid meet" focusable="false" style="pointer-events: none; display: block; width: 100%; height: 100%;" >
        <defs>
            <mask id="Mask">
                <rect width="100%" height="100%" fill="#fff" />
                <polyline stroke-width="2.5" stroke="black" stroke-linecap="square" fill="none" transform="translate(10.373882, 8.762969) rotate(-315.000000) translate(-10.373882, -8.762969) " points="7.99893906 13.9878427 12.7488243 13.9878427 12.7488243 3.53809523"></polyline>
            </mask>
        </defs>
        <rect x="0" y="0" width="20" height="20" fill="white" mask="url(#Mask)" />
    </svg>
    

    and than use this css

    background-repeat: no-repeat;
    background-position: center center;
    background-size: contain;
    background-image: url(your/path/to.svg);
    background-color: var(--color);
    
    0 讨论(0)
  • 2020-11-22 07:10

    You can create your own SCSS function for this. Adding the following to your config.rb file.

    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
    

    Then you can use it in your CSS:

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

    You will need to edit your SVG files and replace any fill attributes in the markup with fill="{color}"

    The icon path is always relative to your images_dir parameter in the same config.rb file.

    Similar to some of the other solutions, but this is pretty clean and keeps your SCSS files tidy!

    0 讨论(0)
  • 2020-11-22 07:11

    A lot of IFs, but if your pre base64 encoded SVG starts:

    <svg fill="#000000
    

    Then the base64 encoded string will start:

    PHN2ZyBmaWxsPSIjMDAwMDAw
    

    if the pre-encoded string starts:

    <svg fill="#bfa76e
    

    then this encodes to:

    PHN2ZyBmaWxsPSIjYmZhNzZl
    

    Both encoded strings start the same:

    PHN2ZyBmaWxsPSIj
    

    The quirk of base64 encoding is every 3 input characters become 4 output characters. With the SVG starting like this then the 6-character hex fill color starts exactly on an encoding block 'boundary'. Therefore you can easily do a cross-browser JS replace:

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

    But tnt-rox answer above is the way to go moving forward.

    0 讨论(0)
  • 2020-11-22 07:12

    It's possible with Sass! The only thing you have to do is to url-encode your svg code. And this is possible with a helper function in Sass. I've made a codepen for this. Look at this:

    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>');
    }
    
    0 讨论(0)
提交回复
热议问题