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

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

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

问题是这样的:

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


当前回答

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

其他回答

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

如果您希望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" height="45" width="45" class="mySVGClass"/>

并应用插件:

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

对于:悬停事件动画,我们可以将样式留在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上查看

我知道你想用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基本上是代码,所以您只需要内容。我使用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