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


437

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

当前,没有一种简单的方法可以嵌入SVG图像,然后可以通过CSS访问SVG元素。有多种使用JS SVG框架的方法,但是如果您要做的只是制作带有过渡状态的简单图标,它们将过于复杂。

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

这是问题:

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


1
不幸的是,img标签不适用于IE中的svg文件,因此请记住这一点。IE识别嵌入标签。无论如何,干得好!

2
对于svg,您应使用“填充” css属性。对于图像,使用“过滤器”是合适的。实际上,“过滤器”对这两者都起作用,但是不必对矢量图形进行所有这些工作。
Samy Bencherif

Answers:


536

首先,在您的HTML中使用IMG标签嵌入SVG图形。我使用Adobe Illustrator制作图形。

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

就像您嵌入普通图像一样。请注意,您需要将IMG设置为具有svg类。“社交链接”类仅出于示例目的。该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


6
为了确保返回的数据可读,有时可能无法在Safari中运行(例如),请});使用}, 'xml');
Joan

29
您甚至可以用替换选择器,img[src$=".svg"]并消除对svg类的需要。
Casey Chu

2
@LeonGaban我认为没有办法定位背景图像的填充。如果可以的话,它将超级有帮助!
德鲁·贝克

3
@LeonGaban有点晚了,但是更好的方法可能是完全删除fill属性,并依靠CSS文件向父svg添加填充。$('#ico_company path').removeAttr('fill')。然后,你可以做#ico_company { fill: #ccc }你的CSS文件
bioball

2
@Soaku可以很容易地让jQuery将所有路径设置为与字体颜色相同,从而执行`var color = $ img.closest('p')。css('color');之类的操作。$ svg.find('path')。attr('fill',color); `但是我认为这是CSS最好的工作。
德鲁·贝克

56

样式

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

1
如果没有宽度attr,它只会创建一个错误的数字。width="170.667"在我的情况
stallingOne

2
这是不完美的,因为它失去了以前的img尺寸。
RichieHH

您好,假设我每个人都有不同的svg和不同的网络颜色。使用这种方法,我所有的svg颜色都与正在循环播放的第一个svg相同。知道我该如何调整以使每种颜色都与以前一样吗?
tnkh

1
请注意,如果您的SVG由也由非path形状(像rect)你需要处理他们在CSS以及
梦幻

33

现在,您可以在大多数现代浏览器(包括Edge,但不包括IE11)中使用CSS filter属性。它适用于SVG图像以及其他元素。您可以使用或修改颜色,尽管它们不允许您单独修改其他颜色。我使用以下CSS类显示图标的“禁用”版本(其中原始图片是具有饱和色的SVG图片):hue-rotateinvert

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

在大多数浏览器中,这使其变为浅灰色。在IE(可能还没有测试过的Opera Mini)中,它的不透明度属性已被明显淡化,尽管它不是灰色,但看起来仍然不错。

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


只是注意到,如果您不想创建图标字体,那么反转是一个很好的解决方案。我使用此jQuery代码根据css color属性更改网站标题中的图标(注意,我正在使用白色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%)"); };
RedClover

很棒的方法。编辑我的SVG xml以添加目标图标颜色,然后使用.icon禁用类将其变灰。
SushiGuy18年

请注意,旧版“探索”不支持过滤器:w3schools.com/cssref/css3_pr_filter.asp
JillAndMe

25

或者,您可以使用CSS mask,授予的浏览器支持不是很好,但是可以使用后备

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

14
MDN指定认为-webkit-mask不应该在任何生产网站使用。
vaindil '16

1
没有颜色的SVG
维沙尔

也许要说,四年后的今天,此解决方案可在所有主流浏览器中使用。刚刚在这里测试,就可以100%确定。
Daniel Lemes

23

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

好处是您可以通过CSS定位SVG的各个部分进行悬停-不需要javascript。

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

您只需要使用如下CSS规则:

#pathidorclass:hover { fill: #303 !important; }

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


3
对于使用AngularJS的用户:<div ng-include="'svg.svg'"></div>
Mikel

但是,将svg数据存储在数据库中并不是一个非常优雅的解决方案。没错,但是从API或CMS中抽出xml / html / svg DOM数据而不是使用模板或其他资产只是感觉不对。
ChristoKiwi '17

谢谢您的贡献...今天最先进的网站嵌套svg数据,以进行各种活动,没有这个答案,我就不会猜到!
webMan

此外,如果您的SVG具有透明区域,则这些区域不会算作悬停,并且您可能会遇到“浮华的悬停”。要解决此问题,只需添加包装器元素(如果方便,可以使用<a>),然后将其添加到CSS规则中。#pathidorclass:hover, .wrapperclass:hover #pathidorclass { fill: green; }甚至只是消除SVG路径的原始悬停,因为无论如何现在您都是通过wrapper元素定位的。
尼尔·梦露'18

18

@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.用业力茉莉花进行单元测试

'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"' +
      'width="64px" height="64px" 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]);
  });
});

1
您的解决方案不起作用,可能是<div ng-include="/icons/my.svg" class="any-class-you-wish"></div>
Guillaume Vincent

@guillaumevincent如果您想使用它,ng-include则只需将此行更改var imgURL = element.attr('src');var imgURL = element.attr('ng-include');
Max

这是一个非常方便的解决方案,但是请谨慎使用它,因为它会严重影响性能-IE在一组文章列表或类似内容上重复显示了5个共享图标。
skxc 2015年

1
IE中的代码有问题。您可以使用just if (typeof(imgClass) !== 'undefined') { $svg.setAttribute("class", imgClass); }代替split和for循环。
罗伯特·博科里

2
很棒的工作!但是对于某些图像,您需要获取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否则页面可能会变得非常慢。
狮子座

16

我意识到您想使用CSS来完成此操作,但是只是提醒一下,如果它是一个小而简单的图像-您始终可以在Notepad ++中将其打开以打开它并更改路径/其他元素的填充:

<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图片,其大小也可能小于此问题的某些代码段。


7

我写了一条指令来解决AngularJS的问题。在此处可用-ngReusableSvg

呈现后,它将替换SVG元素,并将其放置在div元素内,从而使其CSS易于更改。这有助于在不同位置使用不同大小/颜色使用相同的SVG文件。

用法很简单:

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

之后,您可以轻松拥有:

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

您好,感谢您提供此解决方案。我已经尝试过了,它产生了:<div ng-click =“ eventHandler()” ng-class =“ classEventHandler()” style =“ height:30px; width:30px; float:left;” class =“ svg-class” id =“ my-svg” height =“ 30” width =“ 30”> [[object SVGSVGElement]] </ div>然后在html中仅放置[[object SVGSVGElement]]。你知道有什么问题吗?另一个问题,它对性能有很大影响吗?还是可以在页面上的许多svg中使用它?最后,它仍位于角度1.3(弓箭手)上。
bersling

您使用的是哪个版本的angular?没遇到您的问题..也许是与SVG有关?在性能方面,该开关相对较重,我自己用过大约10个,这还不错。.我猜这取决于数量/大小,因此请尝试一下。凉亭有什么问题?您使用的是其他版本,有冲突吗?
Omri Aharon'6

5

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


这是一个很棒的CSS唯一解决方案,再加上从十六进制到过滤器的代码笔都很棒。
RichiGonzález

4

这是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,并且不会考虑任何其他绑定。


2
这很棒!如果您想将其带入一个新的高度,我们有一个包含缓存的更新版本,因此不再需要两次请求相同的SVG。github.com/funkhaus/style-guide/blob/master/template/js/…–
德鲁·贝克

我对此感到有点担心,但自己没有时间去研究它。只是需要快速的东西
Simon_Weaver

1
@DrewBaker实际上,我更担心img标签会请求该文件,然后get再次请求它。我考虑改变srcdata-src该属性img标记,但得出的结论是现代浏览器可能是足够聪明,反正缓存文件
Simon_Weaver

3

这是没有框架的代码,只有纯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)
        })

3

有一个名为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)将触发注入,并且该<img>元素将被src属性中提供的SVG文件的内容替换。

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

  1. 可以隐藏SVG,直到完成注射。如果在加载期间已经应用了样式,这将很重要,否则会导致短暂的“未样式化内容闪烁”。

  2. <img>元素注入自动据为己有。如果您动态添加SVG,则不必担心再次调用注入函数。

  3. 如果将SVG多次注入,则将随机字符串添加到SVG中的每个ID,以避免在文档中多次具有相同的ID。

SVGInject是纯Javascript,可与所有支持SVG的浏览器一起使用。

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


1
我最喜欢此解决方案,因为它负责动态添加的SVG。
VickyB

2

如果我们有更多这样的svg图像,我们也可以利用字体文件。
https://glyphter.com/这样的网站都可以从svgs中获取字体文件。


例如

@font-face {
    font-family: 'iconFont';
    src: url('iconFont.eot');
}
#target{
    color: white;
    font-size:96px;
    font-family:iconFont;
}

5
我个人讨厌“图像作为字体”技术。这使得添加/编辑图像变得困难,增加了许多不必要的标记。字体的应该是字体,图像应该是图片等
德鲁·贝克

同意 您还需要记住/查找分配给角色的图像。但对于将图像用作图标/按钮/项目符号,充当文本而非媒体的特定情况,字体文件也可以作为替代选择
Abhishek Borar 2015年

甚至github也不再使用字体作为图标github.com/blog/2112-delivering-octicons-with-svg
gagarine

2

您可以为此使用数据图像。使用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;
    }
<a class="action-btn delete">&nbsp;</a>

您可以在此处将svg转换为数据网址

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

对于仅希望某些路径/多边形/等在悬停时更改的复杂SVG,这将不起作用。
德鲁·贝克

不,您可以..但是它非常复杂
patelarpan

它只是图标的解决方案
patelarpan,

如果有一些图标。那太好了。Bootstrap 4也使用了这种技术
patelarpan,

2

由于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的结果:

  1. Mozilla Firefox 59.0.2(64位)Linux

在此处输入图片说明

  1. Google Chrome66.0.3359.181(正式版)(64位)Linux

在此处输入图片说明

  1. Opera 53.0.2907.37 Linux

在此处输入图片说明


1

如果您希望jQuery处理DOM中的所有svg元素并且DOM大小合理,那么选择的解决方案就很好。但是,如果您的DOM很大,并且您决定动态加载DOM的一部分,那么仅重新扫描整个DOM来更新svg元素确实没有任何意义。相反,请使用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" height="45" width="45" class="mySVGClass"/>

并应用插件:

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

是的,肯定有更有效的方法来使用我提供的代码。这是我们在生产现场实际使用它的方式。它缓存SVG!github.com/funkhaus/style-guide/blob/master/template/js/...
德鲁贝克

1

对于: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>

在svgshare上检查

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.