Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change color of SVG image using CSS (jQuery SVG image replacement)?

Tags:

jquery

css

svg

This is a self Q&A of a handy piece of code I came up with.

Currently, there isn't an easy way to embed an SVG image and then have access to the SVG elements via CSS. There are various methods of using JS SVG frameworks, but they are overly complicated if all you are doing is making a simple icon with a rollover state.

So here is what I came up with, which I think is by far the easiest way to use SVG files on a website. It takes its concept from the early text-to-image replacement methods, but as far as I am aware has never been done for SVGs.

This is the question:

How do I embed an SVG and change its color in CSS without using a JS-SVG framework?

like image 886
Drew Baker Avatar asked Aug 16 '12 00:08

Drew Baker


People also ask

Can I change the color of an SVG with CSS?

You can't change the color of an image that way. If you load SVG as an image, you can't change how it is displayed using CSS or Javascript in the browser. If you want to change your SVG image, you have to load it using <object> , <iframe> or using <svg> inline.

How do I change the color of an image in CSS?

We can change the image color in CSS by combining the opacity() and drop-shadow() functions in the filter property. We can provide the color of the shadow from the drop-shadow function, and we can set the shadow as thin as possible so that the image's color will only change without forming an actual shadow.

Which property is used to change the color of an SVG using CSS?

The fill property is a presentation attribute used to set the color of a SVG shape.


2 Answers

Firstly, use an IMG tag in your HTML to embed an SVG graphic. I used Adobe Illustrator to make the graphic.

<img id="facebook-logo" class="svg social-link" src="/images/logo-facebook.svg"/> 

This is just like how you'd embed a normal image. Note that you need to set the IMG to have a class of svg. The 'social-link' class is just for examples sake. The ID is not required, but is useful.

Then use this jQuery code (in a separate file or inline in the HEAD).

    /**      * Replace all SVG images with inline SVG      */         jQuery('img.svg').each(function(){             var $img = jQuery(this);             var imgID = $img.attr('id');             var imgClass = $img.attr('class');             var imgURL = $img.attr('src');              jQuery.get(imgURL, function(data) {                 // Get the SVG tag, ignore the rest                 var $svg = jQuery(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);              }, 'xml');          }); 

What the above code does is look for all IMG's with the class 'svg' and replace it with the inline SVG from the linked file. The massive advantage is that it allows you to use CSS to change the color of the SVG now, like so:

svg:hover path {     fill: red; } 

The jQuery code I wrote also ports across the original images ID and classes. So this CSS works too:

#facebook-logo:hover path {     fill: red; } 

Or:

.social-link:hover path {     fill: red; } 

You can see an example of it working here: http://labs.funkhausdesign.com/examples/img-svg/img-to-svg.html

We have a more complicated version that includes caching here: https://github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90

like image 75
Drew Baker Avatar answered Oct 07 '22 15:10

Drew Baker


Style

svg path {     fill: #000; } 

Script

$(document).ready(function() {     $('img[src$=".svg"]').each(function() {         var $img = jQuery(this);         var imgURL = $img.attr('src');         var attributes = $img.prop("attributes");          $.get(imgURL, function(data) {             // Get the SVG tag, ignore the rest             var $svg = jQuery(data).find('svg');              // Remove any invalid XML tags             $svg = $svg.removeAttr('xmlns:a');              // Loop through IMG attributes and apply on SVG             $.each(attributes, function() {                 $svg.attr(this.name, this.value);             });              // Replace IMG with SVG             $img.replaceWith($svg);         }, 'xml');     }); }); 
like image 27
Henrik Albrechtsson Avatar answered Oct 07 '22 16:10

Henrik Albrechtsson