129

我有几个 SVG 图形,我想通过我的外部样式表修改颜色 - 而不是直接在每个 SVG 文件中。我没有将图形嵌入,而是将它们存储在我的图像文件夹中并指向它们。

我以这种方式实现了它们以允许工具提示工作,并且我还将每个都包装在一个<a>标签中以允许链接。

<a href='http://youtube.com/...' target='_blank'><img class='socIcon' src='images/socYouTube.svg' title='View my videos on YouTube' alt='YouTube' /></a>

这是 SVG 图形的代码:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="stylesheets/main.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
<g>
    <path d="M28.44......./>
</g>
</svg>

我将以下内容放在我的外部 CSS 文件 (main.css) 中:

.socIcon g {fill:red;}

但它对图形没有影响。我还尝试了 .socIcon g path {} 和 .socIcon path {}。

有什么不对劲,也许我的实现不允许外部 CSS 修改,或者我错过了一步?我真的很感谢你的帮助!我只需要能够通过我的外部样式表修改 SVG 图形的颜色,但我不能失去工具提示和链接功能。(不过,我也许可以在没有工具提示的情况下生活。)谢谢!

4

15 回答 15

109

如果 SVG 文件内嵌在 HTML 中,您的 main.css 文件只会对 SVG 的内容产生影响:

https://developer.mozilla.org/en/docs/SVG_In_HTML_Introduction

<html>
  <body>
  <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
    <g>
      <path d="M28.44......."/>
    </g>
  </svg>
</html>

如果要将 SVG 保存在文件中,则需要在 SVG 文件中定义 CSS。

您可以使用样式标签来做到这一点:

http://www.w3.org/TR/SVG/styling.html#StyleElementExample

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
     width="50px" height="50px" viewBox="0 0 50 50">
  <defs>
    <style type="text/css"><![CDATA[
      .socIcon g {
        fill:red;
      }
    ]]></style>
  </defs>
  <g>
    <path d="M28.44......./>
  </g>
</svg>

您可以使用服务器端的工具根据活动样式更新样式标签。在 ruby​​ 中,您可以使用 Nokogiri 来实现这一点。SVG 只是 XML。因此,可能有许多可用的 XML 库可以实现这一点。

如果您无法做到这一点,您将不得不像使用 PNG 一样使用它们;为每种样式创建一个集合,并内联保存它们的样式。

于 2013-12-21T16:12:07.003 回答
57

你可以做你想做的事,但有一个(重要的)警告:你的符号中的路径不能通过外部 CSS 独立设置样式——你只能使用这种方法设置整个符号的属性。因此,如果您的符号中有两条路径并希望它们具有不同的填充颜色,这将行不通,但如果您希望所有路径都相同,则应该可以。

在您的 html 文件中,您需要这样的内容:

<style>
  .fill-red { fill: red; }
  .fill-blue { fill: blue; }
</style>

<a href="//www.example.com/">
  <svg class="fill-red">
    <use xlink:href="images/icons.svg#example"></use>
  </svg>
</a>

在外部 SVG 文件中,您需要这样的内容:

<svg xmlns="http://www.w3.org/2000/svg">
   <symbol id="example" viewBox="0 0 256 256">
    <path d="M120.... />
  </symbol>
</svg>

svg将标签上的类(在您的 html 中)从fill-redto和 ta-da交换fill-blue...您有蓝色而不是红色。

您可以通过将外部 CSS 与特定路径上的一些内联 CSS 混合和匹配来部分绕过能够使用外部 CSS 单独定位路径的限制,因为内联 CSS 将优先。如果您在彩色背景上做一个白色图标之类的事情,这种方法会起作用,您想通过外部 CSS 更改背景颜色,但图标本身始终为白色(反之亦然)。因此,使用与以前相同的 HTML 和类似 svg 代码的内容,您将获得红色背景和白色前景路径:

<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="example" viewBox="0 0 256 256">
    <path class="background" d="M120..." />
    <path class="icon" style="fill: white;" d="M20..." />
  </symbol>
</svg>
于 2014-10-13T20:18:17.393 回答
29

您可以使用以下方法在 SVG 文件中包含指向外部 css 文件的链接:

<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="mystyles.css" type="text/css"/>

您需要在打开标签后放置:

<svg>
  <link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="mystyles.css" type="text/css"/>
  <g>
    <path d=.../>
  </g>
</svg>

这不是完美的解决方案,因为您必须修改 svg 文件,但您修改它们一次,然后所有样式更改都可以在所有 svg 文件的一个 css 文件中完成。

于 2019-12-28T21:25:58.403 回答
11

可以通过在 JavaScript 中动态创建样式元素并将其附加到 SVG 元素来设置 SVG 样式。哈克,但它的工作原理。

<object id="dynamic-svg" type="image/svg+xml" data="your-svg.svg">
    Your browser does not support SVG
</object>
<script>
    var svgHolder = document.querySelector('object#dynamic-svg');
    svgHolder.onload = function () {
        var svgDocument = svgHolder.contentDocument;
        var style = svgDocument.createElementNS("http://www.w3.org/2000/svg", "style");

        // Now (ab)use the @import directive to load make the browser load our css
        style.textContent = '@import url("/css/your-dynamic-css.css");';

        var svgElem = svgDocument.querySelector('svg');
        svgElem.insertBefore(style, svgElem.firstChild);
    };
</script>

如果您愿意,您可以在 PHP 中动态生成 JavaScript - 在 JavaScript 中这是可能的这一事实开启了无数的可能性。

于 2017-05-24T12:55:44.883 回答
7

您可以采取的一种方法是使用 CSS 过滤器来更改 SVG 图形在浏览器中的外观。

例如,如果您有一个 SVG 图形在 SVG 代码中使用红色填充颜色,您可以将其变为紫色,并将色调旋转设置为 180 度:

#theIdOfTheImgTagWithTheSVGInIt {
    filter: hue-rotate(180deg);
    -webkit-filter: hue-rotate(180deg);
    -moz-filter: hue-rotate(180deg);
    -o-filter: hue-rotate(180deg);
    -ms-filter: hue-rotate(180deg);
}

尝试使用其他色调旋转设置来找到您想要的颜色。

需要明确的是,上面的 CSS 包含在应用于 HTML 文档的 CSS 中。您在 HTML 代码中设置 img 标记的样式,而不是设置 SVG 代码的样式。

请注意,这不适用于填充黑色或白色或灰色的图形。你必须有一个实际的颜色来旋转该颜色的色调。

于 2015-08-13T14:30:10.503 回答
5

应该可以通过首先内联外部 svg 图像来完成。下面的代码来自Jess Frazelle用内联 SVG 替换所有 SVG 图像。

$('img.svg').each(function(){
  var $img = $(this);
  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);
  });
});
于 2014-07-23T16:28:53.067 回答
4

<object>如果您使用标签嵌入您的 svg ,则可以非常快速地使用外部 css 样式表获得动态样式。

<svg>此示例将在单击父元素时将类添加到根标记。

文件.svg:

<?xml-stylesheet type="text/css" href="../svg.css"?>
 <svg xmlns="http://www.w3.org/2000/svg" viewBox="">
  <g>
   <path/>
  </g>
 </svg>

html:

<a class="parent">
  <object data="file.svg"></object>
</a>

查询:

$(function() {
  $(document).on('click', '.parent', function(){
    $(this).find('object').contents().find('svg').attr("class","selected");
  }
});

点击父元素:

 <svg xmlns="http://www.w3.org/2000/svg" viewBox="" class="selected">

然后你可以管理你的CSS

svg.css:

path {
 fill:none;
 stroke:#000;
 stroke-miterlimit:1.41;
 stroke-width:0.7px;
}

.selected path {
 fill:none;
 stroke:rgb(64, 136, 209);
 stroke-miterlimit:1.41;
 stroke-width:0.7px;
}
于 2017-06-13T12:20:57.210 回答
3
  1. 对于外部样式

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">

  <style>
	@import url(main.css);
  </style>

  <g>
    <path d="M28.44......./>
  </g>
</svg>

  1. 对于内部样式

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">

  <style>
	    .socIcon g {fill:red;}
  </style>

  <g>
    <path d="M28.44......./>
  </g>
</svg>

<img>注意:如果您在标签中包含 SVG,外部样式将不起作用。它将在<div>标签内完美运行

于 2018-12-04T07:35:45.693 回答
2

<image>标签中使用时,出于隐私原因,SVG 必须包含在单个文件中。这个bugzilla 错误详细说明了为什么会这样。不幸的是,您不能使用其他标签,例如 an,<iframe>因为它不能用作链接,因此您必须将 CSS 嵌入<style>文件本身的标签中。

另一种方法是在主 html 文件中包含 SVG 数据,即

<a href='http://youtube.com/...' target='_blank'>
  <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
    <g>
        <path d="M28.44......./>
    </g>
  </svg>
</a>

<link>您可以使用 HTML标记为外部 CSS 文件设置样式。

于 2013-08-25T21:58:16.563 回答
1

什么对我有用:带有@import 规则的样式标签

<defs>
    <style type="text/css">
        @import url("svg-common.css");
    </style>
</defs>
于 2017-09-08T18:36:00.870 回答
0

我知道它是一个旧帖子,但只是为了解决这个问题......你只是在错误的地方使用你的课程:D

首先你可以使用

svg { fill: red; }

在你main.css得到它红色。这确实有效果。您也可以使用节点选择器来获取特定路径。

第二件事是,您将类声明为img-tag。

<img class='socIcon'....

您实际上应该在 SVG 中声明它。如果你有不同的路径,你当然可以定义更多。

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="stylesheets/main.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
<g>
    <path class="myClassForMyPath" d="M28.44......./>
</g>
</svg>

现在你可以改变你main.css喜欢的颜色

.myClassForMyPath {
    fill: yellow;
}
于 2018-02-05T13:58:32.807 回答
0

@leo 这里是 angularJS 版本,再次感谢

G.directive ( 'imgInlineSvg', function () {

return {
    restrict : 'C',
    scope : true,
    link : function ( scope, elem, attrs ) {

        if ( attrs.src ) {

            $ ( attrs ).each ( function () {
                var imgID    = attrs.class;
                var imgClass = attrs.class;
                var imgURL   = attrs.src;

                $.get ( imgURL, function ( data ) {

                    var $svg = $ ( data ).find ( 'svg' );
                    if ( typeof imgID !== 'undefined' ) {
                        $svg = $svg.attr ( 'id', imgID );
                    }

                    if ( typeof imgClass !== 'undefined' ) {
                        $svg = $svg.attr ( 'class', imgClass + ' replaced-svg' );
                    }

                    $svg = $svg.removeAttr ( 'xmlns:a' );

                    elem.replaceWith ( $svg );

                } );

            } );
        }

    }

}

} );
于 2019-01-20T21:31:44.650 回答
0

就我而言,我已经申请display:block了外部班级。

需要试验,适合的地方。

内联svg添加类和样式甚至不会删除上面的空白。

请参阅:display:block应用的位置。

<div class="col-3 col-sm-3 col-md-2  front-tpcard"><a class="noDecoration" href="#">
<img class="img-thumbnail img-fluid"><svg id="Layer_1"></svg>
<p class="cardtxt">Text</p>
</a>
</div>

申请的班级

   .front-tpcard .img-thumbnail{
        display: block; /*To hide the blank whitespace in svg*/
    }

这对我有用。内svg课没用

于 2021-02-15T14:01:20.563 回答
-1

“我实际上会根据用户为我的网站选择的配色方案来更改这些图像的颜色。” -约旦 10 小时前

我建议您为此使用 PHP。没有图标字体真的没有更好的方法,如果你拒绝使用它们,你可以试试这个:

<?php

    header('Content-Type: image/svg+xml');
    echo '<?xml version="1.0" encoding="utf-8"?>';
    $color = $_GET['color'];

?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
    <g>
        <path fill="<?php echo $color; ?>" d="M28.44..."/>
    </g>
</svg>

稍后您可以使用此文件filename.php?color=#ffffff来获取所需颜色的 svg 文件。

于 2013-08-26T09:07:07.677 回答
-2

如果在 Web 浏览器中查看 svg,则此方法将起作用,但是一旦将此代码上传到服务器并且 svg 图标的类被编码为好像它是背景图像,颜色就会丢失并恢复为默认颜色. 即使颜色的 svg 类和 svg 的显示和位置的顶层类都映射到同一个目录,似乎无法从外部样式表更改颜色。

于 2018-04-06T12:11:31.563 回答