Controlling Svg Colors with CSS

How can I change the color of an 'svg' element?

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.

If you want to use the techniques in the page, you need the Modernizr library, where you can check for SVG support and conditionally display or not a fallback image. You can then inline your SVG and apply the styles you need.

See:

#time-3-icon {
fill: green;
}

.my-svg-alternate {
display: none;
}
.no-svg .my-svg-alternate {
display: block;
width: 100px;
height: 100px;
background-image: url(image.png);
}
<svg width="96px" height="96px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
<path id="time-3-icon" d="M256,50C142.229,50,50,142.229,50,256c0,113.77,92.229,206,206,206c113.77,0,206-92.23,206-206
C462,142.229,369.77,50,256,50z M256,417c-88.977,0-161-72.008-161-161c0-88.979,72.008-161,161-161c88.977,0,161,72.007,161,161
C417,344.977,344.992,417,256,417z M382.816,265.785c1.711,0.297,2.961,1.781,2.961,3.518v0.093c0,1.72-1.223,3.188-2.914,3.505
c-37.093,6.938-124.97,21.35-134.613,21.35c-13.808,0-25-11.192-25-25c0-9.832,14.79-104.675,21.618-143.081
c0.274-1.542,1.615-2.669,3.181-2.669h0.008c1.709,0,3.164,1.243,3.431,2.932l18.933,119.904L382.816,265.785z"/>
</svg>

<image class="my-svg-alternate" width="96" height="96" src="ppngfallback.png" />

Controlling SVG colors with CSS

The element referenced by the <use> element is not per se part of the DOM chain, it is only present in the shadow DOM, and hence, you can't access it through your selector.

The solution would be to target directly the <use> element itself, and don't set rules for the inner .primary-stroke so that they can inherit from the <use>.

/*   don't set any direct rule on the .variable ones   otherwise, they won't be able to inherit from the <use>*/
/* target the uses */.stroke-only use[href="#rects"] { stroke: blue; fill: none;}.stroke-and-fill use[href="#rects"] { stroke: blue; fill: green;}
/* this one won't get influenced by the <use> */.fixed { fill: orange; stroke: red;}
svg { display: block; }
<svg width="0" height="0" style="position:absolute;z-index:-1">  <defs>    <g id="rects">      <rect class="variable" x=5 y=5 width=50 height=50 />      <rect class="fixed" x=60 y=5 width=50 height=50 />    </g>  </defs></svg>
<svg class="stroke-only" height=70 > <use href=#rects /></svg>
<svg class="stroke-and-fill" height=70 > <use href=#rects /></svg>

using css to control size and colour of an svg

I'll just quote what is the result of 2 google searches. Please do your own research before asking questions.

Using SVG as an <object>


[…] You can link to an SVG file and retain the ability to affect its parts with CSS by using <object>.
[…] But, if you want the CSS stuff to work, you can't use an external stylesheet or <style> on the document, you need to use a <style> element inside the SVG file itself.

<svg ...>
<style>
/* SVG specific fancy CSS styling here */
</style>
...
</svg>

[…] SVG has a way to declare an external stylesheet, which can be nice for authoring and caching and whatnot. This only works with <object> embedding of SVG files as far as I've tested. You'll need to put this in the SVG file above the opening <svg>

<?xml-stylesheet type="text/css" href="svg.css" ?>

Source: "Using SVG" — CSS-Tricks

Appendix 1

I looked at the codepen project you provided in the comments. Let's take the following file and fix it:

<svg xmlns="http://www.w3.org/2000/svg" width="136" height="136" viewBox="0 0 136 136">
<style type="text/css" media="screen">
<![CDATA[
g {
fill: yellow;
stroke: black;
stroke-width: 1;
transition: fill 1s linear 0s;
}
g:hover {
fill: blue;
}
]]>
</style>
<path d="M121…Z"/>
</svg>

You are trying to style g, which is an SVG group. A group could contain multiple paths, circles, squares, etc. Unfortunately, you don't have any group in this SVG icon. You only have a path.

Additionally, to enable the :hover selector, you would have to enable pointer-events on the elements. This document should provide more information on that.

All in all, here is a working example:

<svg xmlns="http://www.w3.org/2000/svg" width="136" height="136" viewBox="0 0 136 136">
<style type="text/css" media="screen">
<![CDATA[
path { /* TARGET THE CORRECT ELEMENT */
fill: yellow;
stroke: black;
stroke-width: 1;
transition: fill 1s linear 0s;
pointer-events: all; /* ENABLE POINTER EVENTS */
}
path:hover { /* TARGET THE CORRECT ELEMENT */
fill: blue;
}
]]>
</style>
<path d="M121…Z"/>
</svg>

How to style SVG with external CSS?

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.

SVG Changing specific colour - CSS & JS

Use CSS Variables FTW

The easiest way to control SVG colors are using CSS variables (87% browser support).
They not only allows you to control multiple colors but also allows to control colors
on shadow dom elements (when using <use>).

To provide the best experience I use a CSS Variable with a default color and a fallback–should the browser not be the supporting kind

<path style="fill: var(--color-name, #8d5000)" fill="#8d5000" d="M...." />
CSS variable Default Fallback

Sample Image

Example:

(click run code snippet to see result)

/*.robo-1 uses the default colors provided as second parameter in the inline css variables or the fill color if css variables are not supported (like old ie)*/.robo-2 {  --head-color: olive;  --body-color: orange;    --arm-color: maroon;   --feet-color: maroon;    }
.robo-3 { --head-color: magenta; --body-color: purple; --arm-color: hotpink; --feet-color: hotpink; }.robo-4 { --head-color: lightgray; --eye-color: black; --body-color: lightgray; --arm-color: lightgray; --feet-color: lightgray; }
/* hover state */ .robo-4:hover { --head-color: black; --eye-color: white; --body-color: black; --arm-color: black; --feet-color: black; }

svg { width: 20%; }
<!-- master robot svg --> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" id="robot" class="robo-1">    <!-- head -->    <path style="fill:var(--head-color, black)" fill="black" d="M751.8 203.2H639.9l90.7-114.7c3.4 1.3 7.1 1.9 10.9 1.9 19.6 0 35.5-18 35.5-40.3C777 28 761.1 10 741.5 10S706 28 706 50.3c0 8.9 2.5 17.1 6.9 23.8L610.7 203.2H403.9c9.8-9.9 16-24.3 16-40.3 0-29.9-21.5-54.1-48.1-54.1s-48.1 24.2-48.1 54.1c0 16 6.2 30.4 16 40.3h-91.5a114.8 114.8 0 0 0-114.5 115l34.3 306c0 63.5 51.3 115 114.5 115h435c63.2 0 114.5-51.5 114.5-115l34.3-306c0-63.5-51.2-115-114.5-115z"/>    <!-- eyes -->    <path style="fill:var(--eye-color, white)" fill="white" d="M332.9 541.4a32.2 32.2 0 0 1 0-64.4 32 32 0 0 1 32 32.2 32 32 0 0 1-32 32.2zm318.2 9.2c-19 0-34.3-13.4-34.3-29.9s15.4-29.9 34.3-29.9c19 0 34.3 13.4 34.3 29.9s-15.3 29.9-34.3 29.9z"/>    <!-- body -->    <path style="fill:var(--body-color, black)" fill="black" d="M385.4 753c-8.7 15-13.6 32.2-13.6 50.6 0 57.2 47.7 103.5 106.5 103.5h50.4c58.8 0 106.5-46.4 106.5-103.5 0-18.4-5-35.7-13.6-50.6H385.4z"/>     <!-- arms -->    <path style="fill:var(--arm-color, black)" fill="black" d="M325.1 753a44.4 44.4 0 0 0-5.9 21.9c0 22.6 18.4 42.2 41.6 52l.1.6a108 108 0 0 1-.5-10c-1.9-12.7-5.5-38.6 8.8-64.4h-44.1zm314.8 0c4.2 14.2 9.4 37.7 7.1 63.5a64.3 64.3 0 0 0 38.1-63.5h-45.2z"/>    <!-- feets -->    <path style="fill:var(--feet-color, black)" fill="black" d="M572.9 916.5c-31.6 6.8-31.6 9.1-31.6 9.1l-8.8-.2a40 40 0 0 0-7.2 23.2c0 20.3 14.4 36.8 32.1 36.8 17.7 0 32.1-16.5 32.1-36.8a38.5 38.5 0 0 0-16.6-32.1zm-118.7 6.8s-6.8-2-16.8-6.5a40.2 40.2 0 0 0-17.5 34.1c0 21.6 15.4 39.1 34.3 39.1 19 0 34.3-17.5 34.3-39.1 0-10.4-3.6-19.9-9.5-26.9l-24.8-.7z"/></svg>

<!-- the clones are coming! --><svg viewBox="0 0 1000 1000" class="robo-2"> <use xlink:href="#robot"></use></svg><svg viewBox="0 0 1000 1000" class="robo-3"> <use xlink:href="#robot"></use></svg><svg viewBox="0 0 1000 1000" class="robo-4"> <use xlink:href="#robot"></use></svg>

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

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

Problems with controlling SVG colors from outside through CSS

why not simply remove the style part inside the SVG ?

(and create your own css [in the html HEAD] with the colors you want)

other just use css !impotant in your css

html { background-color: #eeeeee; }
.icon{
height: 6rem;
width: 6rem;
}
svg { fill:red; }

/* add: */
.st1 { stroke:blue !important; }
path { stroke:orange !important; }

SVG fill with css variables

Okay here we go... I will first explain why it does not work and then I will show an alternative.

Why your approach doesn't work

In your example the svg is not part of the DOM. So you cannot use css to modify the attributes of the svg.

What you are doing is adding an inline-style to the svg in your url. Since the browser does not recognise --primary-color as a color it doesn't work.

An alternative approach

An alternative approach is to put the svg in the html and fake a background. I did this by absolute positioning the svg and moving it to the background with z-index.

Do note you will have to modify the svg or the positioning to place the background in the way you want. Normally you would use background-size for this. But with some effort you can replicate this behaviour within the svg or position it better by using css.

:root {  --primary-color: hsl(332, 61%, 78%);}
div { width: 100px; height: 100px; }
.test { background: var(--primary-color);}.icon{ /*postion relative for absolute positioning to work*/ position: relative; }.icon>svg{ position: absolute; top: 0px; right: 0px; left: 0px; bottom: 0px; z-index: -1;}.icon>svg>path{ /*target the image with css*/ fill: var(--primary-color);}
<div class="test">  Testing the css variable color</div>
<div class="icon"> <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 129 129' id='background'><path d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z'/> </svg> <p>Text goes here...</p></div>


Related Topics



Leave a reply



Submit