如何使用外部CSS设置SVG样式?

时间:2013-08-25 21:50:26

标签: html css svg stylesheet external

我有几个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图形的颜色,但我不能失去工具提示和链接能力。 (虽然我可能没有工具提示,但也可以。)谢谢!

15 个答案:

答案 0 :(得分:72)

如果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>

您可以使用服务器端的工具根据活动样式更新样式标记。在红宝石中,你可以通过Nokogiri实现这一目标。 SVG只是XML。因此,可能有许多XML库可以实现这一目标。

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

答案 1 :(得分:37)

您可以通过一个(重要的)警告来执行您想要的操作:符号中的路径无法通过外部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-red更改为fill-blue和ta-da ...您有蓝色而不是红色。

通过将外部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>

答案 2 :(得分:6)

可以通过在JavaScript中动态创建样式元素并将其附加到SVG元素来设置SVG的样式。 Hacky,但它确实有效。

<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中可以实现这一点,从而开启了无数的可能性。

答案 3 :(得分:4)

您可以采取的一种方法是使用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代码的样式。

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

答案 4 :(得分:3)

应该可以通过首先内联外部svg图像来完成。看这里例如:

Replace All Svg Images With Inline Svg | JAVASCRIPT | Code Snippet Library by Jess Frazelle

答案 5 :(得分:2)

<image>标记中使用时,出于隐私原因,SVG必须包含在单个文件中。这个bugzilla bug详细说明了为什么会这样。遗憾的是,您无法使用其他标记,例如<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>

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

答案 6 :(得分:2)

  

“我实际上会根据用户为我的网站选择的颜色方案来更改这些图片的颜色。” - Jordan 10 hours ago

我建议您使用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文件。

答案 7 :(得分:2)

如果您使用<object>标记嵌入svg,则可以使用外部css样式表获得动态样式的快速解决方案。

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

file.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>

Jquery:

$(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;
}

答案 8 :(得分:1)

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

首先你可以使用

svg { fill: red; }

在你的main.css中让它变红。这确实有效。您也可以使用节点选择器来获取特定的路径。

第二件事是,你将类声明为img - 标签。

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

答案 9 :(得分:0)

对我有用:带@import规则的样式标记

<defs>
    <style type="text/css">
        @import url("svg-common.css");
    </style>
</defs>

答案 10 :(得分:0)

  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>标签内完美运行

答案 11 :(得分: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 );

                } );

            } );
        }

    }

}

} );

答案 12 :(得分:0)

您可以使用以下方法在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文件,但是您必须修改它们一次,然后所有样式更改都可以在一个css文件中针对所有svg文件进行。

答案 13 :(得分:0)

就我而言,我在外部类中应用了 ((null? to-append-right) to-append-left)

需要在合适的地方进行试验。

inside inline 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*/ } 类不起作用

答案 14 :(得分:-1)

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