img src SVG改变填充颜色

问题描述 投票:256回答:15

HTML

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

CSS

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

上面的svg加载并且本身是fill: #fff但是当我使用上面的css尝试将其更改为黑色时它不会改变,这是我第一次使用SVG并且我不确定为什么它不起作用。

css image css3 svg
15个回答
213
投票

您需要使SVG成为内联SVG。您可以通过向图像添加类svg来使用此脚本:

/*
 * 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');

});

然后,现在,如果你这样做:

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

或者可能:

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

这有效!

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

上述脚本的致谢:How to change color of SVG image using CSS (jQuery SVG image replacement)?


4
投票

要扩展@gringo答案,其他答案中描述的Javascript方法有效,但要求用户下载不必要的图像文件,而IMO则会使您的代码膨胀。

我认为更好的方法是将所有单色矢量图形迁移到webfont文件。我过去曾经使用过Fort Awesome,它可以很好地将SVG格式的自定义图标/图像与您可能使用的任何第三方图标(Font Awesome,Bootstrap图标等)合并到一个webfont文件中用户必须下载。您也可以自定义它,因此您只包含您正在使用的第三方图标。这减少了页面必须进行的请求数量,并且您的整体页面权重,特别是如果您已经包含任何第三方图标库。

如果你更喜欢更面向开发的选项,你可以使用Google "npm svg webfont",并使用一个最适合你环境的节点模块。

有一次,您已经完成了这两个选项中的任何一个,那么您可以通过CSS轻松更改颜色,而且很有可能,您在此过程中加快了网站的速度。


1
投票

您的主要问题是您从<img>标签导入svg,这将隐藏SVG结构。

您需要将<svg>标签与<use>结合使用才能获得所需的效果。要使其工作,您需要将id提供给您要在SVG文件<path id='myName'...>中使用的路径,然后才能从<use xlink:href="#myName"/>标记中检索它们。试试下面的剪辑。

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

请注意,如果要从#加载SVG(而不是将其嵌入到HTML中),可以在片段external source之前放置任何URL。此外,通常您不指定填充CSS。最好考虑在SVG中使用fill:"currentColor"。然后将使用相应元素的CSS颜色值。


1
投票

如果您只是在真实颜色和黑白之间切换图像,可以将一个选择器设置为:

{滤波器:无;}

和另一个:

{filter:grayscale(100%);}

0
投票

知道这是一个老问题,但最近我们遇到了同样的问题,我们从服务器端解决了这个问题。这是一个特定于php的答案,但我很肯定其他envs有类似的东西。而不是使用img标签,你从一开始就将svg渲染为svg。

public static function print_svg($file){
    $iconfile = new \DOMDocument();
    $iconfile->load($file);
    $tag = $iconfile->saveHTML($iconfile->getElementsByTagName('svg')[0]);
    return $tag;
}

现在,当您渲染文件时,您将获得完整的内联svg


-1
投票

如果您可以访问JQuery,那么扩展到Praveen的答案可以通过以下方式以编程方式更改SVG中不同嵌套元素的颜色:

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

在find中,您可以提到需要更改颜色的不同元素。


-1
投票

由于SVG基本上是代码,因此您只需要内容。我使用PHP来获取内容,但您可以使用任何您想要的内容。

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

然后,我在div容器中“按原样”打印内容

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

最后在CSS上将规则设置为容器的SVG子级

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

我用一个材料图标SVG得到了这个结果:

Mozilla Firefox 59.0.2(64位)Linux

enter image description here

谷歌Chrome V66.0.3359.181(Build oficial)(64位)Linux

enter image description here

Opera 53.0.2907.37 Linux

enter image description here


112
投票

如果你的目标只是改变徽标的颜色,并且你不一定需要使用CSS,那么不要像之前的一些答案所建议的那样使用javascript或jquery。

要准确回答原始问题,只需:

  1. 在文本编辑器中打开logo.svg
  2. 寻找fill: #fff并用fill: #000替换它

例如,在文本编辑器中打开时,logo.svg可能看起来像这样:

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

...只需更改填充并保存。


50
投票

您可以将svg设置为掩码。这样设置背景颜色就可以作为填充颜色。

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/

请注意,此方法不适用于Edge浏览器。您可以访问此网站查看:https://caniuse.com/#search=mask


33
投票

尝试纯CSS:

.logo-img {
  // to black
  filter: invert(1);
  // or to blue
  // filter: invert(1) sepia(1) saturate(5) hue-rotate(175deg);
}

本文中的更多信息https://blog.union.io/code/2017/08/10/img-svg-fill/


14
投票

@Praveen的答案是可靠的。

我无法让它在我的工作中做出回应,所以我为它做了一个jquery悬停功能。

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

11
投票

为什么不用svg图像或图像创建webfont,在css中导入webfont然后只使用css颜色属性更改字形的颜色?不需要JavaScript


11
投票

这个答案是基于https://stackoverflow.com/a/24933495/3890888的答案,但是在那里使用的脚本是纯JavaScript版本。

您需要使SVG成为内联SVG。您可以通过向图像添加类svg来使用此脚本:

/*
 * 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);

    });

});

然后,现在,如果你这样做:

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

或者可能:

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

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


11
投票

2018:如果你想要一个动态颜色,不想使用javascript而不想要内联SVG,请使用CSS变量。适用于Chrome,Firefox和Safari。编辑:和边缘

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

在你的SVG中,用style="fill: #000"替换style="fill: var(--color_fill)"的任何实例。


6
投票

首先,您必须将SVG注入HTML DOM。

有一个名为SVGInject的开源库可以为您完成此任务。它使用onload属性来触发注入。

这是使用SVGInject的最小示例:

<html>
  <head>
    <script src="svg-inject.min.js"></script>
  </head>
  <body>
    <img src="image.svg" onload="SVGInject(this)" />
  </body>
</html>

加载图像后,onload="SVGInject(this)将触发注入,<img>元素将被src属性中提供的SVG文件的内容替换。

它解决了SVG注入的几个问题:

  1. 注射完成后,可以隐藏SVG。如果在加载时已经应用了样式,则这很重要,否则会导致短暂的“无格式内容闪烁”。
  2. <img>元素自动注入。如果动态添加SVG,则不必担心再次调用注入函数。
  3. 如果SVG被多次注入,则向SVG中的每个ID添加随机字符串,以避免在文档中多次使用相同的ID。

SVGInject是简单的Javascript,适用于所有支持SVG的浏览器。

免责声明:我是SVGInject的合着者

© www.soinside.com 2019 - 2024. All rights reserved.