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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18434094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 12:35:46  来源:igfitidea点击:

How to style SVG with external CSS?

htmlcsssvgstylesheetexternal

提问by Jordan H

I have several SVG graphics I'd like to modify the colors of via my external style sheets - not directly within each SVG file. I'm not putting the graphics in-line, but storing them in my images folder and pointing to them.

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

I have implemented them in this way to allow tooltips to work, and I also wrapped each in an <a>tag to allow a link.

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

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

And here is the code of the SVG graphic:

这是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>

I put the following in my external CSS file (main.css):

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

.socIcon g {fill:red;}

Yet it has no effect on the graphic. I also tried .socIcon g path {} and .socIcon path {}.

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

Something isn't right, perhaps my implementation doesn't allow external CSS modifications, or I missed a step? I'd really appreciate your help! I just need the ability to modify the colors of the SVG graphic via my external stylesheet, but I cannot lose the tooltip and link ability. (I may be able to live without tooltips though.) Thanks!

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

采纳答案by RGB

Your main.css file would only have an effect on the content of the SVG if the SVG file is included inline in the HTML:

如果 SVG 文件内联包含在 HTML 中,则 main.css 文件只会对 SVG 的内容产生影响:

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

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>

If you want to keep your SVG in files, the CSS needs to be defined inside of the SVG file.

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

You can do it with a style tag:

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

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

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>

You could use a tool on the server side to update the style tag depending on the active style. In ruby you could achieve this with Nokogiri. SVG is just XML. So there are probably many XML libraries available that can probably achieve this.

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

If you're not able to do that, you will have to just have to use them as though they were PNGs; creating a set for each style, and saving their styles inline.

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

回答by Adam Korman

You can do what you want, with one (important) caveat: the paths within your symbol can't be styled independently via external CSS -- you can only set the properties for the entire symbol with this method. So, if you have two paths in your symbol and want them to have different fill colors, this won't work, but if you want all your paths to be the same, this should work.

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

In your html file, you want something like this:

在你的 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>

And in the external SVG file you want something like this:

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

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

Swap the class on the svgtag (in your html) from fill-redto fill-blueand ta-da... you have blue instead of red.

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

You can partially get around the limitation of being able to target the paths separately with external CSS by mixing and matching the external CSS with some in-line CSS on specific paths, since the in-line CSS will take precedence. This approach would work if you're doing something like a white icon against a colored background, where you want to change the color of the background via the external CSS but the icon itself is always white (or vice-versa). So, with the same HTML as before and something like this svg code, you'll get you a red background and a white foreground path:

您可以通过在特定路径上混合和匹配外部 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>

回答by Pete

It is possible to style an SVG by dynamically creating a style element in JavaScript and appending it to the SVG element. Hacky, but it works.

可以通过在 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>

You could generate the JavaScript dynamically in PHP if you want to - the fact that this is possible in JavaScript opens a myriad of possibilities.

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

回答by Simon White

One approach you can take is just to use CSS filters to change the appearance of the SVG graphics in the browser.

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

For example, if you have an SVG graphic that uses a fill color of red within the SVG code, you can turn it purple with a hue-rotate setting of 180 degrees:

例如,如果您的 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);
}

Experiment with other hue-rotate settings to find the colors you want.

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

To be clear, the above CSS goes in the CSS that is applied to your HTML document. You are styling the img tag in the HTML code, not styling the code of the SVG.

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

And note that this won't work with graphics that have a fill of black or white or gray. You have to have an actual color in there to rotate the hue of that color.

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

回答by vhanahrni

A very quick solution to have dynamic style with an external css stylesheet, in case you are using the <object>tag to embed your svg.

使用外部 css 样式表具有动态样式的非常快速的解决方案,以防您使用<object>标签嵌入 svg。

This example will add a class to the root <svg>tag on click on a parent element.

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

file.svg :

文件.svg :

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

html :

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

on click parent element :

单击父元素:

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

then you can manage your css

然后你可以管理你的css

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

回答by Leo

It should be possible to do by first inlining the external svg images. The code below comes from replace all SVG images with inline SVGby Jess Frazelle.

应该可以通过首先内联外部 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);
  });
});

回答by Jacek Mamot

You can include in your SVG files link to external css file using:

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

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

You need to put this after opening tag:

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

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

It's not perfect solution, because you have to modify svg files, but you modify them once and than all styling changes can be done in one css file for all svg files.

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

回答by Dwza

I know its an old post, but just to clear this problem... you just using your classes at the wrong place :D

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

First of all you could use

首先你可以使用

svg { fill: red; }

in your main.cssto get it red. This does have effect. You could propably use node selectors as well to get specific pathes.

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

Second thing is, you declaired the class to the img-Tag.

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

<img class='socIcon'....

You actually should declair it inside your SVG. if you have diffrent pathes you could define more of course.

您实际上应该在 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>

now you could change the color in your main.csslike

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

.myClassForMyPath {
    fill: yellow;
}

回答by Robert Longson

When used in an <image>tag SVG must be contained in a single file for privacy reasons. This bugzilla bughas more details on exactly why this is so. Unfortunately you can't use a different tag such as an <iframe>because that won't work as a link so you'll have to embed the CSS in a <style>tag within the file itself.

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

One other way to do this would be to have the SVG data within the main html file i.e.

另一种方法是在主 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>

You could style that with an external CSS file using the HTML <link>tag.

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

回答by SeinopSys

"I am actually going to change the colors of these images based on what color scheme the user has chosen for my site."- Jordan10 hours ago

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

I suggest you to use PHP for this. There's really no better way to do this without icon fonts, and if you resist using them, you could try this:

我建议你为此使用 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>

And later you could use this file as filename.php?color=#ffffffto get the svg file in the desired color.

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