[html] How to style SVG with external CSS?

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!

This question is related to html css svg stylesheet external

The answer is


@leo here is the angularJS version, thanks again

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

                } );

            } );
        }

    }

}

} );

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.

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


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.


What works for me: style tag with @import rule

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

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.

In your html file, you want something like this:

<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 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 svg tag (in your html) from fill-red to fill-blue and ta-da... you have blue instead of red.

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:

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

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.


In my case, I have applied display:block in outer class.

Need to experiment, where it fits.

Inside inline svg adding class and style does not even remove the above white-space.

See: where the display:block gets applied.

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

The class applied

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

This worked for me. Inner svg class did not worked


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

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


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

First of all you could use

svg { fill: red; }

in your main.css to get it red. This does have effect. You could probably use node selectors as well to get specific paths.

Second thing is, you declared the class to the img-tag.

<img class='socIcon'....

You actually should declare it inside your SVG. if you have different paths you could define more of course.

<?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.css like

.myClassForMyPath {
    fill: yellow;
}

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

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

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


  1. For External styles

_x000D_
_x000D_
<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">_x000D_
_x000D_
  <style>_x000D_
 @import url(main.css);_x000D_
  </style>_x000D_
_x000D_
  <g>_x000D_
    <path d="M28.44......./>_x000D_
  </g>_x000D_
</svg>
_x000D_
_x000D_
_x000D_

  1. For Internal Styles

_x000D_
_x000D_
<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">_x000D_
_x000D_
  <style>_x000D_
     .socIcon g {fill:red;}_x000D_
  </style>_x000D_
_x000D_
  <g>_x000D_
    <path d="M28.44......./>_x000D_
  </g>_x000D_
</svg>
_x000D_
_x000D_
_x000D_

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


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.

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

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

on click parent element :

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

then you can manage your 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;
}

When used in an <image> tag SVG must be contained in a single file for privacy reasons. This bugzilla bug has 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.

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

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


Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to svg

How to extract svg as file from web page How to display svg icons(.svg files) in UI using React Component? Why don’t my SVG images scale using the CSS "width" property? How to show SVG file on React Native? Easiest way to use SVG in Android? IE11 meta element Breaks SVG img src SVG changing the styles with CSS How to use SVG markers in Google Maps API v3 Embedding SVG into ReactJS How to change the color of an svg element?

Examples related to stylesheet

How to display 3 buttons on the same line in css Vertical align middle with Bootstrap responsive grid How to style SVG with external CSS? Add a link to an image in a css style sheet background-image: url("images/plaid.jpg") no-repeat; wont show up How to play CSS3 transitions in a loop? Stylesheet not updating Make a table fill the entire window HTML not loading CSS file In which order do CSS stylesheets override?

Examples related to external

How to invoke function from external .c file in C? How to style SVG with external CSS? How to call execl() in C with the proper arguments? Android saving file to external storage Find location of a removable SD card PHP ini file_get_contents external url Getting the 'external' IP address in Java Eclipse: How to build an executable jar with external jar?