当前位置 : 首页 » 互动问答 » 正文

img src SVG changing the fill color

分类 : 互动问答 | 发布时间 : 2014-07-24 20:15:31 | 评论 : 12 | 浏览 : 253387 | 喜欢 : 193

html

<img src="logo.svg" alt="Logo" class="logo-img">

css

.logo-img path {
  fill: #000;
}

The above svg loads and is natively fill: #fff but when I use the above css to try change it to black it doesn't change, this is my first time playing with SVG and I am not sure why it's not working.

回答(12)

  • 1楼
  • You need to make the SVG to be an inline SVG. You can make use of this script, by adding a class svg to the image:

    /*
     * Replace all SVG images with inline SVG
     */
    jQuery('img.svg').each(function(){
        var $img = jQuery(this);
        var imgID = $img.attr('id');
        var imgClass = $img.attr('class');
        var imgURL = $img.attr('src');
    
        jQuery.get(imgURL, function(data) {
            // Get the SVG tag, ignore the rest
            var $svg = jQuery(data).find('svg');
    
            // Add replaced image's ID to the new SVG
            if(typeof imgID !== 'undefined') {
                $svg = $svg.attr('id', imgID);
            }
            // Add replaced image's classes to the new SVG
            if(typeof imgClass !== 'undefined') {
                $svg = $svg.attr('class', imgClass+' replaced-svg');
            }
    
            // Remove any invalid XML tags as per http://validator.w3.org
            $svg = $svg.removeAttr('xmlns:a');
    
            // Check if the viewport is set, if the viewport is not set the SVG wont't scale.
            if(!$svg.attr('viewBox') && $svg.attr('height') && $svg.attr('width')) {
                $svg.attr('viewBox', '0 0 ' + $svg.attr('height') + ' ' + $svg.attr('width'))
            }
    
            // Replace image with new SVG
            $img.replaceWith($svg);
    
        }, 'xml');
    
    });
    

    And then, now if you do:

    .logo-img path {
      fill: #000;
    }
    

    Or may be:

    .logo-img path {
      background-color: #000;
    }
    

    This works!

    Fiddle: http://jsfiddle.net/wuSF7/462/

    Credits for the above script: How to change color of SVG image using CSS (jQuery SVG image replacement)?

  • 2楼
  • If your goal is just to change the color of the logo, and you don't necessarily NEED to use CSS, then don't use javascript or jquery as was suggested by some previous answers.

    To precisely answer the original question, just:

    1. Open your logo.svg in a text editor.

    2. look for fill: #fff and replace it with fill: #000

    For example, your logo.svg might look like this when opened in a text editor:

    <svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="none"/>
      <path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" fill="#fff"/>
    </svg>
    

    ... just change the fill and save.

  • 3楼
  • You could set your svg as a mask. That way setting a background-color would act as your fill color.

    HTML

    <div class="logo"></div>
    

    CSS

    .logo {
        background-color: red;
        -webkit-mask: url(logo.svg) no-repeat center;
        mask: url(logo.svg) no-repeat center;
    }
    

    JSFiddle: https://jsfiddle.net/KuhlTime/2j8exgcb/

    Please note that this method is not working for the Edge browser. You can check that by going to this website: https://caniuse.com/#search=mask

  • 4楼
  • The answer from @Praveen is solid.

    I couldn't get it to respond in my work, so I made a jquery hover function for it.

    CSS

    .svg path {
       transition:0.3s all !important;
    }
    

    JS / JQuery

    // code from above wrapped into a function
    replaceSVG();
    
    // hover function
    // hover over an element, and find the SVG that you want to change
    $('.element').hover(function() {
        var el = $(this);
        var svg = el.find('svg path');
        svg.attr('fill', '#CCC');
    }, function() {
        var el = $(this);
        var svg = el.find('svg path');
        svg.attr('fill', '#3A3A3A');
    });
    
  • 5楼
  • Why not create a webfont with your svg image or images, import the webfont in the css and then just change the color of the glyph using the css color attribute? No javascript needed

  • 6楼
  • This answer is based on answer https://stackoverflow.com/a/24933495/3890888 but with a plain JavaScript version of the script used there.

    You need to make the SVG to be an inline SVG. You can make use of this script, by adding a class svg to the image:

    /*
     * Replace all SVG images with inline SVG
     */
    document.querySelectorAll('img.svg').forEach(function(img){
        var imgID = img.id;
        var imgClass = img.className;
        var imgURL = img.src;
    
        fetch(imgURL).then(function(response) {
            return response.text();
        }).then(function(text){
    
            var parser = new DOMParser();
            var xmlDoc = parser.parseFromString(text, "text/xml");
    
            // Get the SVG tag, ignore the rest
            var svg = xmlDoc.getElementsByTagName('svg')[0];
    
            // Add replaced image's ID to the new SVG
            if(typeof imgID !== 'undefined') {
                svg.setAttribute('id', imgID);
            }
            // Add replaced image's classes to the new SVG
            if(typeof imgClass !== 'undefined') {
                svg.setAttribute('class', imgClass+' replaced-svg');
            }
    
            // Remove any invalid XML tags as per http://validator.w3.org
            svg.removeAttribute('xmlns:a');
    
            // Check if the viewport is set, if the viewport is not set the SVG wont't scale.
            if(!svg.getAttribute('viewBox') && svg.getAttribute('height') && svg.getAttribute('width')) {
                svg.setAttribute('viewBox', '0 0 ' + svg.getAttribute('height') + ' ' + svg.getAttribute('width'))
            }
    
            // Replace image with new SVG
            img.parentNode.replaceChild(svg, img);
    
        });
    
    });
    

    And then, now if you do:

    .logo-img path {
      fill: #000;
    }
    

    Or may be:

    .logo-img path {
      background-color: #000;
    }
    

    JSFiddle: http://jsfiddle.net/erxu0dzz/1/

  • 7楼
  • To expand on @gringo answer, the Javascript method described in other answers works, but requires the user to download unnecessary image files, and IMO, it bloats your code.

    I think a better approach would be to to migrate all 1-color vector graphics to a webfont file. I've used Fort Awesome in the past, and it works great to combine your custom icons/images in SVG format, along with any 3rd party icons you may be using (Font Awesome, Bootstrap icons, etc.) into a single webfont file the user has to download. You can also customize it, so you only include the 3rd party icons you're using. This reduces the number of requests the page has to make, and you're overall page weight, especially if you're already including any 3rd party icons libraries.

    If you prefer a more dev oriented option, you could Google "npm svg webfont", and use one of the node modules that's most appropriate for your environment.

    Once, you've done either of those two options, then you could easily change the color via CSS, and most likely, you've sped up your site in the process.

  • 8楼
  • 2018: If you want a dynamic color, do not want to use javascript and do not want an inline SVG, use a CSS variable. Works in Chrome, Firefox and Safari.

    <svg>
        <use xlink:href="logo.svg" style="--color_fill: #000;"></use>
    </svg>
    

    In your SVG, replace any instances of style="fill: #000" with style="fill: var(--color_fill)".

  • 9楼
  • Since SVG is basically code, you need just contents. I used PHP to obtain content, but you can use whatever you want.

    <?php
    $content    = file_get_contents($pathToSVG);
    ?>
    

    Then, I've printed content "as is" inside a div container

    <div class="fill-class"><?php echo $content;?></div>
    

    To finnaly set rule to container's SVG childs on CSS

    .fill-class > svg { 
        fill: orange;
    }
    

    I got this results with a material icon SVG:

    Mozilla Firefox 59.0.2 (64-bit) Linux

    enter image description here

    Google Chrome66.0.3359.181 (Build oficial) (64 bits) Linux

    enter image description here

    Opera 53.0.2907.37 Linux

    enter image description here

  • 10楼
  • If you have access to JQuery, then extending to Praveen's answer one can programatically change color of different nested elements inside SVG by:

    $('svg').find('path, text').css('fill', '#ffffff');

    Within find, you can mention different elements that needs to be changed in color.

  • 11楼
  • The main problem in your case is that you are importing the svg from an <img> tag which will hide the SVG structure.

    You need to use the <svg> tag in conjunction with the <use> to get the desired effect. To make it work, you need to give an id to the path you want to use in the SVG file <path id='myName'...> to then be able to retrieve them from the <use xlink:href="#myName"/> tag. Try the snipped below.

    .icon {
      display: inline-block;
      width: 2em;
      height: 2em;
      transition: .5s;
      fill: currentColor;
      stroke-width: 5;
      }
      .icon:hover {
        fill: rgba(255,255,255,0);
        stroke: black;
        stroke-width: 2;
        }
    
    .red {
      color: red;
      }
    
    .blue {
      color: blue;
      }
    <svg width="0" height="0">
      <defs>
        <path id="home" d="M100 59.375l-18.75-18.75v-28.125h-12.5v15.625l-18.75-18.75-50 50v3.125h12.5v31.25h31.25v-18.75h12.5v18.75h31.25v-31.25h12.5z"/>
    </svg>
    
      
      <span class="icon red">
              <svg viewbox="0 0 100 100">
                <use xlink:href="#home"/>
              </svg>
            </span>
      
        <span class="icon blue">
              <svg viewbox="0 0 100 100">
                <use xlink:href="#home"/>
              </svg>
            </span>

    Note that you can put any URL before the fragment # if you want to load the SVG from an external source (and not embed it into your HTML). Also, usually you do not specify the fill into the CSS. It's better to consider using fill:"currentColor" within the SVG itself. The corresponding element's CSS color value will then be used in place.

相关阅读:

100% width background image with an 'auto' height

How to get a responsive button in bootstrap 3

Resize image proportionally with CSS?

How to insert spaces/tabs in text using HTML/CSS?

IE8 support for CSS Media Query

CSS text-decoration underline color

jQuery "blinking highlight" effect on div?

CSS - Make divs align horizontally

Make a div 100% height of the browser window

Make a div 100% height of the browser window