How to modify the fill color of an SVG image when being served as background image?

Placing the SVG output directly inline with the page code I am able to simply modify fill colors with CSS like so:

polygon.mystar {
    fill: blue;
}​

circle.mycircle {
    fill: green;
}

This works great, however I'm looking for a way to modify the "fill" attribute of an SVG when it's being served as a BACKGROUND-IMAGE.

html {      
    background-image: url(../img/bg.svg);
}

How can I change the colors now? Is it even possible?

For reference, here are the contents of my external SVG file:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve">
<polygon class="mystar" fill="#3CB54A" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679 
    118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/>
<circle class="mycircle" fill="#ED1F24" cx="202.028" cy="58.342" r="12.26"/>
</svg>

You can use CSS masks, With the 'mask' property, you create a mask that is applied to an element.

.icon {
    background-color: red;
    -webkit-mask-image: url(icon.svg);
    mask-image: url(icon.svg);
}

For more see this great article: https://codepen.io/noahblon/post/coloring-svgs-in-css-background-images


I needed something similar and wanted to stick with CSS. Here are LESS and SCSS mixins as well as plain CSS that can help you with this. Unfortunately, it's browser support is a bit lax. See below for details on browser support.

LESS mixin:

.element-color(@color) {
  background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="@{color}" ... /></g></svg>');
}

LESS usage:

.element-color(#fff);

SCSS mixin:

@mixin element-color($color) {
  background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="#{$color}" ... /></g></svg>');
}

SCSS usage:

@include element-color(#fff);

CSS:

// color: red
background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="red" ... /></g></svg>');

Here is more info on embedding the full SVG code into your CSS file. It also mentioned browser compatibility which is a bit too small for this to be a viable option.


One way to do this is to serve your svg from some server side mechanism. Simply create a resource server side that outputs your svg according to GET parameters, and you serve it on a certain url.

Then you just use that url in your css.

Because as a background img, it isn't part of the DOM and you can't manipulate it. Another possibility would be to use it regularly, embed it in a page in a normal way, but position it absolutely, make it full width & height of a page and then use z-index css property to put it behind all the other DOM elements on a page.


Yet another approach is to use mask. You then change the background color of the masked element. This has the same effect as changing the fill attribute of the svg.

HTML:

<glyph class="star"/>
<glyph class="heart" />
<glyph class="heart" style="background-color: green"/>
<glyph class="heart" style="background-color: blue"/>

CSS:

glyph {
    display: inline-block;
    width:  24px;
    height: 24px;
}

glyph.star {
  -webkit-mask: url(star.svg) no-repeat 100% 100%;
  mask: url(star.svg) no-repeat 100% 100%;
  -webkit-mask-size: cover;
  mask-size: cover;
  background-color: yellow;
}

glyph.heart {
  -webkit-mask: url(heart.svg) no-repeat 100% 100%;
  mask: url(heart.svg) no-repeat 100% 100%;
  -webkit-mask-size: cover;
  mask-size: cover;
  background-color: red;
}

You will find a full tutorial here: http://codepen.io/noahblon/blog/coloring-svgs-in-css-background-images (not my own). It proposes a variety of approaches (not limited to mask).


Use the sepia filter along with hue-rotate, brightness, and saturation to create any color we want.

.colorize-pink {
  filter: brightness(0.5) sepia(1) hue-rotate(-70deg) saturate(5);
}

https://css-tricks.com/solved-with-css-colorizing-svg-backgrounds/