How to style SVG with external CSS?

2019-01-03 13:43发布

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.

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 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:

<?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):

.socIcon g {fill:red;}

Yet it has no effect on the graphic. I also tried .socIcon g path {} and .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!

12条回答
冷血范
2楼-- · 2019-01-03 14:19

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

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:

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

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.

查看更多
做个烂人
3楼-- · 2019-01-03 14:19

This method will work if the svg is viewed within a web browser but as soon as this code is uploaded to the sever and the class for the svg icon is coded as if it was a background image the color is lost and back to the default color. Seems like the color can not be changed from the external style sheet even though both the svg class for the color and the top layer class for the display and position of the svg are both mapped to the same directory.

查看更多
狗以群分
4楼-- · 2019-01-03 14:20

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:

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.

You can do it with a style tag:

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.

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.

查看更多
混吃等死
5楼-- · 2019-01-03 14:20

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

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

    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=#ffffff to get the svg file in the desired color.

查看更多
放荡不羁爱自由
6楼-- · 2019-01-03 14:23

What works for me: style tag with @import rule

<defs>
    <style type="text/css">
        @import url("svg-common.css");
    </style>
</defs>
查看更多
Animai°情兽
7楼-- · 2019-01-03 14:28
  1. For External styles

<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. For Internal Styles

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

Note: External Styles will not work if you include SVG inside <img> tag. It will work perfectly inside <div> tag

查看更多
登录 后发表回答