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

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

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

问题是这样的:

我如何在CSS中嵌入SVG并改变其颜色而不使用JS-SVG框架?


当前回答

下面是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');

        }
    };

然后对img标签应用data-bind="svgConvert: true"。

这个解决方案完全用SVG替换了img标记,任何附加的绑定都不会受到尊重。

其他回答

我知道你想用CSS来完成这个,但只是一个提醒,以防它是一个小的,简单的图像-你可以随时在notepad++中弹出它,并更改路径/whatever元素的填充:

<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图像也可能比这个问题的一些代码片段更小。

风格

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

我用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
}

首先,在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;
}

Or:

.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

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