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

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

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

问题是这样的:

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


当前回答

如果我们有大量这样的svg图像,我们还可以借助字体文件。 像https://glyphter.com/这样的网站可以从我们的svgs中获取字体文件。


E.g.

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

其他回答

有一个名为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注入的几个问题:

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

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

声明:我是SVGInject的合著者

下面是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标记,任何附加的绑定都不会受到尊重。

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

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

这使得它在大多数浏览器中呈浅灰色。在IE中(可能还有我没有测试过的Opera Mini),它会因为不透明属性而明显褪色,尽管不是灰色,但看起来仍然很不错。

下面是Twemoji铃铛图标的四个不同CSS类的示例:original(黄色)、上面的“disabled”类、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>

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

因为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材质图标得到了这个结果:

Firefox 59.0.2(64位)Linux

谷歌Chrome66.0.3359.181 (Build official)(64位)Linux

Opera 53.0.2907.37 Linux