如何使用 CSS(jQuery SVG 图像替换)更改 SVG 图像的颜色?

Posted

技术标签:

【中文标题】如何使用 CSS(jQuery SVG 图像替换)更改 SVG 图像的颜色?【英文标题】:How to change color of SVG image using CSS (jQuery SVG image replacement)? 【发布时间】:2019-11-08 03:25:33 【问题描述】:

这是我想出的一段方便代码的自我问答。

目前,没有一种简单的方法可以嵌入 SVG 图像,然后通过 CSS 访问 SVG 元素。使用 JS SVG 框架的方法有很多种,但如果你所做的只是制作一个带有翻转状态的简单图标,它们就过于复杂了。

这就是我想出的,我认为这是迄今为止在网站上使用 SVG 文件的最简单方法。它的概念来自早期的文本到图像替换方法,但据我所知,SVG 从未这样做过。

这是问题:

如何在不使用 JS-SVG 框架的情况下嵌入 SVG 并在 CSS 中更改其颜色?

【问题讨论】:

不幸的是,img 标签不适用于 IE 中的 svg 文件,因此请记住这一点。 IE 识别嵌入标签。无论如何,干得好! 对于 svg,您应该使用“填充”css 属性。对于图像,使用“过滤器”是合适的。 “过滤器”实际上对两者都有效,但没有必要为矢量图形做所有这些工作。 【参考方案1】:

首先,在 html 中使用 IMG 标签嵌入 SVG 图形。我使用 Adob​​e Illustrator 制作图形。

<img id="facebook-logo" class="svg social-link" src="/images/logo-facebook.svg"/>

这就像嵌入普通图像一样。请注意,您需要将 IMG 设置为 svg 类。 'social-link' 类只是为了举例。 ID 不是必需的,但很有用。

然后使用这个 jQuery 代码(在单独的文件中或在 HEAD 中内联)。

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

                // Replace image with new SVG
                $img.replaceWith($svg);

            , 'xml');

        );

上述代码的作用是查找所有具有“svg”类的 IMG,并将其替换为链接文件中的内联 SVG。巨大的优势是它现在允许您使用 CSS 来更改 SVG 的颜色,如下所示:

svg:hover path 
    fill: red;

我编写的 jQuery 代码还可以跨原始图像 ID 和类进行移植。所以这个 CSS 也可以:

#facebook-logo:hover path 
    fill: red;

或者:

.social-link:hover path 
    fill: red;

你可以在这里看到一个例子: http://labs.funkhausdesign.com/examples/img-svg/img-to-svg.html

我们有一个更复杂的版本,其中包括缓存: https://github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90

【讨论】:

这太棒了!我一直在寻找一种保持标记干净的方法,但仍然允许访问 svg “innards”以在 CSS 中使用。这应该可以,但是我收到 JS 错误:“XMLHttpRequest 无法加载 file:///H:/svg/test/test.svg。Access-Control-Allow-Origin 不允许 Origin null。”有什么想法吗? 我的猜测是因为您在本地运行它并遇到跨域问题。将它放在服务器上,它应该可以工作。 如果你把它放在 onDocumentReady 处理程序中,你可能会得到 FOUC(无样式内容的闪烁)效果,它在用 替换它们之前呈现原始 标签。如果在呈现每个 标记之前有某种方法可以立即运行它,那将是完美的。我想您也可以使用 CSS 隐藏“img.svg”元素,以便它们仅在替换发生后呈现。 它有时在 Safari 中可能不起作用(例如),为确保返回的数据可读,请将 $.get 的 ); 替换为 , 'xml'); 您甚至可以将选择器替换为 img[src$=".svg"] 并消除对 svg 类的需要。【参考方案2】:

风格

svg path 
    fill: #000;

脚本

$(document).ready(function() 
    $('img[src$=".svg"]').each(function() 
        var $img = jQuery(this);
        var imgURL = $img.attr('src');
        var attributes = $img.prop("attributes");

        $.get(imgURL, function(data) 
            // Get the SVG tag, ignore the rest
            var $svg = jQuery(data).find('svg');

            // Remove any invalid XML tags
            $svg = $svg.removeAttr('xmlns:a');

            // Loop through IMG attributes and apply on SVG
            $.each(attributes, function() 
                $svg.attr(this.name, this.value);
            );

            // Replace IMG with SVG
            $img.replaceWith($svg);
        , 'xml');
    );
);

【讨论】:

如果你没有宽度属性,它只会创建一个错误的数字。 width="170.667" 在我的情况下 这并不完美,因为它丢失了以前的 img 尺寸。 您好,假设我有不同的 svg,每个都有不同的颜色。使用这种方法,我所有的 svg 颜色都与循环的第一个 svg 相同。知道如何解决这个问题,使每种颜色都与以前一样吗? 请注意,如果您的 svg 也是由非 path 形状(如 rect)制作的,您还需要在 css 中处理它们【参考方案3】:

您现在可以在most modern browsers 中使用CSS filter property(包括Edge,但不包括IE11)。它适用于 SVG 图像以及其他元素。您可以使用hue-rotateinvert 来修改颜色,尽管它们不允许您单独修改不同的颜色。我使用以下 CSS 类来显示图标的“禁用”版本(其中原始是饱和颜色的 SVG 图片):

.disabled 
    opacity: 0.4;
    filter: grayscale(100%);
    -webkit-filter: grayscale(100%);

这使它在大多数浏览器中变成浅灰色。在 IE(可能还有 Opera Mini,我还没有测试过)中,它被 opacity 属性明显淡化了,虽然它不是灰色的,但看起来仍然相当不错。

这是一个示例,其中Twemoji 铃铛图标有四个不同的 CSS 类:原始(黄色)、上面的“禁用”类、hue-rotate(绿色)和invert(蓝色)。

.twa-bell 
  background-image: url("https://twemoji.maxcdn.com/svg/1f514.svg");
  display: inline-block;
  background-repeat: no-repeat;
  background-position: center center;
  height: 3em;
  width: 3em;
  margin: 0 0.15em 0 0.3em;
  vertical-align: -0.3em;
  background-size: 3em 3em;

.grey-out 
  opacity: 0.4;
  filter: grayscale(100%);
  -webkit-filter: grayscale(100%);

.hue-rotate 
  filter: hue-rotate(90deg);
  -webkit-filter: hue-rotate(90deg);

.invert 
  filter: invert(100%);
  -webkit-filter: invert(100%);
<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <span class="twa-bell"></span>
  <span class="twa-bell grey-out"></span>
  <span class="twa-bell hue-rotate"></span>
  <span class="twa-bell invert"></span>
</body>

</html>

【讨论】:

刚刚注意到如果您不想创建图标字体,反转是一个很好的解决方案。我使用此 jQuery 代码根据 css 颜色属性更改网站标题中的图标(注意我使用的是白色 png 图标):if ($('.w3-top img').css("color") == "rgb(0, 0, 0)") $('.w3-top img').css("filter", "invert(100%)"); $('.w3-top img').css("-webkit-filter", "invert(100%)"); ; 很棒的方法。编辑我的 SVG xml 以添加目标图标颜色,然后使用 .icon-disabled 类将其变灰。 请注意旧的探索不支持过滤器:w3schools.com/cs-s-ref/css3_pr_filter.asp【参考方案4】:

或者,您可以使用 CSS mask,授予 browser support 不好,但您可以使用后备

.frame 
    background: blue;
    -webkit-mask: url(image.svg) center / contain no-repeat;

【讨论】:

MDN specifies -webkit-mask 不应在任何生产网站上使用。 不给 svg 着色 也许有必要说,四年后的现在,这个解决方案在所有主流浏览器中都可以使用。刚刚在这里测试,它是 100% 好的。【参考方案5】:

如果您可以在您的页面中包含文件(php 包含或通过您选择的 CMS 包含),您可以添加 SVG 代码并将其包含到您的页面中。这与将 SVG 源代码粘贴到页面中的效果相同,但会使页面标记更清晰。

好处是您可以通过 CSS 定位 SVG 的某些部分以进行悬停——无需 javascript

http://codepen.io/chriscoyier/pen/evcBu

你只需要使用这样的 CSS 规则:

#pathidorclass:hover  fill: #303 !important; 

请注意,!important 位是覆盖填充颜色所必需的。

【讨论】:

对于那些使用 AngularJS 的人:&lt;div ng-include="'svg.svg'"&gt;&lt;/div&gt; 虽然在数据库中存储 svg 数据并不是一个非常优雅的解决方案。没错,但是从 API 或 CMS 中提取 xml/html/svg DOM 数据而不是使用模板或其他资产感觉不对。 此外,如果您的 SVG 具有透明区域,这些区域不会被视为悬停,您可能会遇到“闪烁悬停”。要解决这个问题,只需添加一个包装元素(一个 ,如果方便的话),然后将其添加到 CSS 规则中。 #pathidorclass:hover, .wrapperclass:hover #pathidorclass fill: green; 或者甚至只是消除 SVG 路径的原始悬停,因为无论如何您现在都通过包装器元素定位它。【参考方案6】:

@Drew Baker 给出了一个很好的解决方案来解决这个问题。代码工作正常。然而,那些使用 AngularJs 的人可能会发现对 jQuery 有很多依赖。因此,我认为为 AngularJS 用户粘贴一个遵循@Drew Baker 解决方案的代码是个好主意。

AngularJs方式相同的代码

1. Html:在你的html文件中使用波纹管标签:

<svg-image src="/icons/my.svg" class="any-class-you-wish"></svg-image>

2.指令:这将是您识别标签所需的指令:

'use strict';
angular.module('myApp')
  .directive('svgImage', ['$http', function($http) 
    return 
      restrict: 'E',
      link: function(scope, element) 
        var imgURL = element.attr('src');
        // if you want to use ng-include, then
        // instead of the above line write the bellow:
        // var imgURL = element.attr('ng-include');
        var request = $http.get(
          imgURL,
          'Content-Type': 'application/xml'
        );

        scope.manipulateImgNode = function(data, elem)
          var $svg = angular.element(data)[4];
          var imgClass = elem.attr('class');
          if(typeof(imgClass) !== 'undefined') 
            var classes = imgClass.split(' ');
            for(var i = 0; i < classes.length; ++i)
              $svg.classList.add(classes[i]);
            
          
          $svg.removeAttribute('xmlns:a');
          return $svg;
        ;

        request.success(function(data)
          element.replaceWith(scope.manipulateImgNode(data, element));
        );
      
    ;
  ]);

3. CSS

.any-class-you-wish
    border: 1px solid red;
    height: 300px;
    width:  120px

4.使用 karma-jasmine 进行单元测试

'use strict';

describe('Directive: svgImage', function() 

  var $rootScope, $compile, element, scope, $httpBackend, apiUrl, data;

  beforeEach(function() 
    module('myApp');

    inject(function($injector) 
      $rootScope = $injector.get('$rootScope');
      $compile = $injector.get('$compile');
      $httpBackend = $injector.get('$httpBackend');
      apiUrl = $injector.get('apiUrl');
    );

    scope = $rootScope.$new();
    element = angular.element('<svg-image src="/icons/icon-man.svg" class="svg"></svg-image>');
    element = $compile(element)(scope);

    spyOn(scope, 'manipulateImgNode').andCallThrough();
    $httpBackend.whenGET(apiUrl + 'me').respond(200, );

    data = '<?xml version="1.0" encoding="utf-8"?>' +
      '<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->' +
      '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' +
      '<!-- Obj -->' +
      '<!-- Obj -->' +
      '<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"' +
      '  viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">' +
        '<g>' +
          '<path fill="#F4A902" d=""/>' +
          '<path fill="#F4A902" d=""/>' +
        '</g>' +
      '</svg>';
    $httpBackend.expectGET('/icons/icon-man.svg').respond(200, data);
  );

  afterEach(function() 
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  );

  it('should call manipulateImgNode atleast once', function () 
    $httpBackend.flush();
    expect(scope.manipulateImgNode.callCount).toBe(1);
  );

  it('should return correct result', function () 
    $httpBackend.flush();
    var result = scope.manipulateImgNode(data, element);
    expect(result).toBeDefined();
  );

  it('should define classes', function () 
    $httpBackend.flush();
    var result = scope.manipulateImgNode(data, element);
    var classList = ["svg"];
    expect(result.classList[0]).toBe(classList[0]);
  );
);

【讨论】:

您的解决方案不起作用,可能是&lt;div ng-include="/icons/my.svg" class="any-class-you-wish"&gt;&lt;/div&gt; @guillaumevincent 如果你想将它与ng-include 一起使用,那么只需将这一行var imgURL = element.attr('src'); 更改为var imgURL = element.attr('ng-include'); 这是一个非常方便的解决方案,但在过度使用它时要小心,因为它会严重影响性能 - I.E.一组 5 个在文章列表或类似内容上重复出现的共享图标。 你的IE代码有问题。您可以只使用 if (typeof(imgClass) !== 'undefined') $svg.setAttribute("class", imgClass); 而不是 split 和 for 循环。 很棒的工作!但是对于某些图像,您需要获取 svg 的第一个元素 (angular.element(data)[0];) 并使其与 IE 一起使用 if ($svg.getAttribute('class')) $svg.setAttribute('class', $svg.getAttribute('class') + ' ' + imgClass); else $svg.setAttribute('class', imgClass); 。此外,您可能需要将cache: true 添加到$http.get 的选项中,否则您的页面可能会变得非常慢。【参考方案7】:

TL/DR:去这里-> https://codepen.io/sosuke/pen/Pjoqqp

解释:

我假设你有这样的 html:

<img src="/img/source.svg" class="myClass">

一定要走过滤路线,即。您的 svg 很可能是黑色或白色。您可以应用过滤器使其成为您想要的任何颜色,例如,我有一个黑色 svg,我想要薄荷绿色。我首先将其反转为白色(从技术上讲,它是全 RGB 颜色)然后使用色调饱和度等。要正确:

filter: invert(86%) sepia(21%) saturate(761%) hue-rotate(92deg) brightness(99%) contrast(107%);

更好的是,您可以使用工具将所需的十六进制转换为过滤器:https://codepen.io/sosuke/pen/Pjoqqp

【讨论】:

【参考方案8】:

我知道你想用 CSS 来完成这个,但只是提醒一下,以防它是一个小而简单的图像 - 你可以随时在 Notepad++ 中打开它并更改路径/whateverelement 的填充:

<path style="fill:#010002;" d="M394.854,205.444c9.218-15.461,19.102-30.181,14.258-49.527
    ...
    C412.843,226.163,402.511,211.451,394.854,205.444z"/>

它可以节省大量丑陋的脚本。很抱歉,如果它偏离基础,但有时可能会忽略简单的解决方案。

...即使交换多个 svg 图像的大小也可能比该问题的某些代码 sn-ps 小。

【讨论】:

【参考方案9】:

我写了一个指令来用 AngularJS 解决这个问题。它是可用的here - ngReusableSvg。

它在渲染后替换 SVG 元素,并将其放置在 div 元素中,使其 CSS 易于更改。这有助于在不同的地方使用不同的尺寸/颜色使用相同的 SVG 文件。

用法很简单:

<object oa-reusable-svg
        data="my_icon.svg"
        type="image/svg+xml"
        class="svg-class"
          // given to prevent UI glitches at switch time
        >
</object>

之后,您可以轻松拥有:

.svg-class svg 
    fill: red; // whichever color you want

【讨论】:

您好,感谢您提供此解决方案。我已经尝试过了,它产生: [[object SVGSVGElement]] 然后在 html 中放置 [[object SVGSVGElement]]。你知道有什么问题吗?另一个问题,它对性能有很大影响,还是我可以在页面上的许多 svg 上使用它?最后,它仍然在 angular 1.3(凉亭)上。 您使用的是哪个版本的 Angular?还没有遇到你的问题..也许是 SVG 的问题?性能方面,开关相对较重,我自己在 10 上使用过它,它很好。我想这取决于数量/大小,所以试用它并进行试验。凉亭有什么问题?您是否使用不同的版本并且存在冲突?【参考方案10】:

这是基于接受的答案的knockout.js 的版本:

重要提示:它实际上也需要 jQuery 来替换,但我认为它可能对某些人有用。

ko.bindingHandlers.svgConvert =
    
        'init': function ()
        
            return  'controlsDescendantBindings': true ;
        ,

        'update': function (element, valueAccessor, allBindings, viewModel, bindingContext)
        
            var $img = $(element);
            var imgID = $img.attr('id');
            var imgClass = $img.attr('class');
            var imgURL = $img.attr('src');

            $.get(imgURL, function (data)
            
                // Get the SVG tag, ignore the rest
                var $svg = $(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');

                // Replace image with new SVG
                $img.replaceWith($svg);

            , 'xml');

        
    ;

然后将data-bind="svgConvert: true" 应用到您的img 标签。

此解决方案将 img 标记完全替换为 SVG,并且不会考虑任何其他绑定。

【讨论】:

这太棒了!如果您想将其提升到一个新的水平,我们有一个包含缓存的更新版本,因此相同的 SVG 不会被请求两次。 github.com/funkhaus/style-guide/blob/master/template/js/… 我有点担心,但没有时间自己研究。只是需要一些快速的东西 @DrewBaker 实际上我更担心 img 标签会请求文件,然后 get 会再次请求它。我考虑将src 更改为data-src 标签上的data-src 属性,但得出的结论是现代浏览器可能足够聪明,可以缓存文件【参考方案11】:

有一个名为 SVGInject 的开源库,它使用 onload 属性来触发注入。你可以在https://github.com/iconfu/svg-inject找到GitHub项目

这是一个使用 SVGInject 的最小示例:

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

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

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

    在注入完成之前可以隐藏 SVG。如果在加载期间已经应用了样式,这一点很重要,否则会导致短暂的“无样式内容闪烁”。

    &lt;img&gt; 元素会自动注入。如果动态添加SVG,就不用担心再次调用注入函数了。

    在 SVG 中的每个 ID 中添加一个随机字符串,以避免在多次注入 SVG 时在文档中多次使用相同的 ID。

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

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

【讨论】:

【参考方案12】:

这里没有框架代码,只有纯js:

document.querySelectorAll('img.svg').forEach(function(element) 
            var imgID = element.getAttribute('id')
            var imgClass = element.getAttribute('class')
            var imgURL = element.getAttribute('src')

            xhr = new XMLHttpRequest()
            xhr.onreadystatechange = function() 
                if(xhr.readyState == 4 && xhr.status == 200) 
                    var svg = xhr.responseXML.getElementsByTagName('svg')[0];

                    if(imgID != null) 
                         svg.setAttribute('id', imgID);
                    

                    if(imgClass != null) 
                         svg.setAttribute('class', imgClass + ' replaced-svg');
                    

                    svg.removeAttribute('xmlns:a')

                    if(!svg.hasAttribute('viewBox') && svg.hasAttribute('height') && svg.hasAttribute('width')) 
                        svg.setAttribute('viewBox', '0 0 ' + svg.getAttribute('height') + ' ' + svg.getAttribute('width'))
                    
                    element.parentElement.replaceChild(svg, element)
                
            
            xhr.open('GET', imgURL, true)
            xhr.send(null)
        )

【讨论】:

【参考方案13】:

如果我们有更多此类 svg 图像,我们还可以借助字体文件。https://glyphter.com/ 之类的网站可以从我们的 svg 中获取字体文件。


例如

@font-face 
    font-family: 'iconFont';
    src: url('iconFont.eot');

#target
    color: white;
    font-size:96px;
    font-family:iconFont;

【讨论】:

我个人讨厌“图像作为字体”技术。它使添加/编辑图像变得困难,添加了许多无意义的标记。字体应该是字体,图像应该是图像等。 同意。您还需要记住/查找分配给角色的图像。但是对于将图像用作图标/按钮/项目符号的特定情况,更多地充当文本而不是媒体,字体文件也可以作为替代方案 即使 github 也不再使用字体作为图标 github.com/blog/2112-delivering-octicons-with-svg【参考方案14】:

您可以为此使用数据图像。使用 data-image(data-URI) 你可以像内联一样访问 SVG。

这是使用纯 CSS 和 SVG 的翻转效果。

我知道它混乱,但你可以这样做。

 .action-btn 
    background-size: 20px 20px;
    background-position: center center;
    background-repeat: no-repeat;
    border-width: 1px;
    border-style: solid;
    border-radius: 30px;
    height: 40px;
    width: 60px;
    display: inline-block;
 

.delete 
     background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Capa_1' fill='#FB404B' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='482.428px' height='482.429px' viewBox='0 0 482.428 482.429' style='enable-background:new 0 0 482.428 482.429;' xml:space='preserve'%3e%3cg%3e%3cg%3e%3cpath d='M381.163,57.799h-75.094C302.323,25.316,274.686,0,241.214,0c-33.471,0-61.104,25.315-64.85,57.799h-75.098 c-30.39,0-55.111,24.728-55.111,55.117v2.828c0,23.223,14.46,43.1,34.83,51.199v260.369c0,30.39,24.724,55.117,55.112,55.117 h210.236c30.389,0,55.111-24.729,55.111-55.117V166.944c20.369-8.1,34.83-27.977,34.83-51.199v-2.828 C436.274,82.527,411.551,57.799,381.163,57.799z M241.214,26.139c19.037,0,34.927,13.645,38.443,31.66h-76.879 C206.293,39.783,222.184,26.139,241.214,26.139z M375.305,427.312c0,15.978-13,28.979-28.973,28.979H136.096 c-15.973,0-28.973-13.002-28.973-28.979V170.861h268.182V427.312z M410.135,115.744c0,15.978-13,28.979-28.973,28.979H101.266 c-15.973,0-28.973-13.001-28.973-28.979v-2.828c0-15.978,13-28.979,28.973-28.979h279.897c15.973,0,28.973,13.001,28.973,28.979 V115.744z'/%3e%3cpath d='M171.144,422.863c7.218,0,13.069-5.853,13.069-13.068V262.641c0-7.216-5.852-13.07-13.069-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C158.074,417.012,163.926,422.863,171.144,422.863z'/%3e%3cpath d='M241.214,422.863c7.218,0,13.07-5.853,13.07-13.068V262.641c0-7.216-5.854-13.07-13.07-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C228.145,417.012,233.996,422.863,241.214,422.863z'/%3e%3cpath d='M311.284,422.863c7.217,0,13.068-5.853,13.068-13.068V262.641c0-7.216-5.852-13.07-13.068-13.07 c-7.219,0-13.07,5.854-13.07,13.07v147.154C298.213,417.012,304.067,422.863,311.284,422.863z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e ");
     border-color:#FB404B;
     
 
 
 .delete:hover 
     background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Capa_1' fill='#fff' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='482.428px' height='482.429px' viewBox='0 0 482.428 482.429' style='enable-background:new 0 0 482.428 482.429;' xml:space='preserve'%3e%3cg%3e%3cg%3e%3cpath d='M381.163,57.799h-75.094C302.323,25.316,274.686,0,241.214,0c-33.471,0-61.104,25.315-64.85,57.799h-75.098 c-30.39,0-55.111,24.728-55.111,55.117v2.828c0,23.223,14.46,43.1,34.83,51.199v260.369c0,30.39,24.724,55.117,55.112,55.117 h210.236c30.389,0,55.111-24.729,55.111-55.117V166.944c20.369-8.1,34.83-27.977,34.83-51.199v-2.828 C436.274,82.527,411.551,57.799,381.163,57.799z M241.214,26.139c19.037,0,34.927,13.645,38.443,31.66h-76.879 C206.293,39.783,222.184,26.139,241.214,26.139z M375.305,427.312c0,15.978-13,28.979-28.973,28.979H136.096 c-15.973,0-28.973-13.002-28.973-28.979V170.861h268.182V427.312z M410.135,115.744c0,15.978-13,28.979-28.973,28.979H101.266 c-15.973,0-28.973-13.001-28.973-28.979v-2.828c0-15.978,13-28.979,28.973-28.979h279.897c15.973,0,28.973,13.001,28.973,28.979 V115.744z'/%3e%3cpath d='M171.144,422.863c7.218,0,13.069-5.853,13.069-13.068V262.641c0-7.216-5.852-13.07-13.069-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C158.074,417.012,163.926,422.863,171.144,422.863z'/%3e%3cpath d='M241.214,422.863c7.218,0,13.07-5.853,13.07-13.068V262.641c0-7.216-5.854-13.07-13.07-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C228.145,417.012,233.996,422.863,241.214,422.863z'/%3e%3cpath d='M311.284,422.863c7.217,0,13.068-5.853,13.068-13.068V262.641c0-7.216-5.852-13.07-13.068-13.07 c-7.219,0-13.07,5.854-13.07,13.07v147.154C298.213,417.012,304.067,422.863,311.284,422.863z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e ");        
     background-color: #FB404B;
    
&lt;a class="action-btn delete"&gt;&amp;nbsp;&lt;/a&gt;

您可以在此处将您的 svg 转换为数据 url

    https://codepen.io/elliz/full/ygvgay https://websemantics.uk/tools/svg-to-background-image-conversion/

【讨论】:

这不适用于您只希望某些路径/多边形/等在悬停时更改的复杂 SVG 吗? 不,你可以..但它非常复杂 这只是图标的解决方案 如果有些使用图标。然后它很棒。 Bootstrap 4 也使用了这个技术【参考方案15】:

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

    Google Chrome66.0.3359.181(官方构建)(64 位)Linux

    Opera 53.0.2907.37 Linux

【讨论】:

【参考方案16】:

如果您希望 jQuery 处理 DOM 中的所有 svg 元素并且您的 DOM 大小合理,则选择的解决方案很好。但是,如果您的 DOM 很大,并且您决定动态加载 DOM 的一部分,那么为了更新 svg 元素而必须重新扫描整个 DOM 确实没有意义。相反,请使用 jQuery 插件来执行此操作:

/**
 * A jQuery plugin that loads an svg file and replaces the jQuery object with its contents.
 *
 * The path to the svg file is specified in the src attribute (which normally does not exist for an svg element).
 *
 * The width, height and class attributes in the loaded svg will be replaced by those that exist in the jQuery object's
 * underlying html. Note: All other attributes in the original element are lost including the style attribute. Place
 * any styles in a style class instead.
 */
(function ($) 
    $.fn.svgLoader = function () 
        var src = $(this).attr("src");
        var width = this.attr("width");
        var height = this.attr("height");
        var cls = this.attr("class");
        var ctx = $(this);

        // Get the svg file and replace the <svg> element.
        $.ajax(
            url: src,
            cache: false
        ).done(function (html) 
            let svg = $(html);
            svg.attr("width", width);
            svg.attr("height", height);
            svg.attr("class", cls);
            var newHtml = $('<a></a>').append(svg.clone()).html();
            ctx.replaceWith(newHtml);
        );

        return this;
    ;

(jQuery));

在您的 html 中,指定一个 svg 元素,如下所示:

<svg src="images/someSvgFile.svg"   class="mySVGClass"/>

并应用插件:

$(".mySVGClass").svgLoader();

【讨论】:

是的,当然有更有效的方法来使用我提供的代码。以下是我们在生产站点上实际使用它的方式。它缓存 SVG! github.com/funkhaus/style-guide/blob/master/template/js/…【参考方案17】:

对于 :hover 事件动画,我们可以将样式留在 svg 文件中, 像一个

<svg xmlns="http://www.w3.org/2000/svg">
<defs>
  <style>
  rect 
    fill:rgb(165,225,75);
    stroke:none;
    transition: 550ms ease-in-out;
    transform-origin:125px 125px;
  
  rect:hover 
    fill:rgb(75,165,225);
    transform:rotate(360deg);
  
  </style>
</defs>
  <rect x='50' y='50' width='150' height='150'/>
</svg>

check this on svgshare

【讨论】:

【参考方案18】:
.carousel-control-prev-icon 
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='rgb(3,122,247)' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e");

更改颜色:fill='rgb(3,122,247)'

【讨论】:

以上是关于如何使用 CSS(jQuery SVG 图像替换)更改 SVG 图像的颜色?的主要内容,如果未能解决你的问题,请参考以下文章

在 React 中用内联 svg 替换图像元素

如何将图案图像动态添加到 svg?

如何使用 jQuery SVG 插件设置 SVG 矩形元素的背景图像?

如何使用 JQuery 控制基于 CSS 的 SVG 动画?

SVG 对象从外部 CSS 更改颜色

javascript 使用内联SVG替换所有SVG图像