Change SVG fill color in :before or :after CSS

mnsth picture mnsth · Feb 2, 2014 · Viewed 36k times · Source

I have a SVG graphic put like this:

a::before { content: url(filename.svg); }

When I hover over the tag, I really want the SVG to change the fill color, without loading a new SVG file, as I have now:

a:hover::before { content: url(filename_white.svg); }

Is this possible to achieve using JavaScript, jQuery or just pure CSS that I am not aware of?

Thanks.

Answer

lmaooooo picture lmaooooo · Feb 18, 2017

The accepted answer is incorrect, this is actually possible by applying a workaround with an SVG mask and background-color:

p:after {
  width: 48px;
  height: 48px;
  display: inline-block;
  content: '';
  -webkit-mask: url(https://gist.githubusercontent.com/mmathys/fbbfbc171233a30e478ad5b87ec4f5d8/raw/cd9219e336b8f3b85579015bdce9665def091bb8/heart.svg) no-repeat 50% 50%;
  mask: url(https://gist.githubusercontent.com/mmathys/fbbfbc171233a30e478ad5b87ec4f5d8/raw/cd9219e336b8f3b85579015bdce9665def091bb8/heart.svg) no-repeat 50% 50%;
  -webkit-mask-size: cover;
  mask-size: cover;
}

.red:after {
  background-color: red;
}

.green:after {
  background-color: green;
}

.blue:after {
  background-color: blue;
}
<p class="red">red heart</p>
<p class="green">green heart</p>
<p class="blue">blue heart</p>

You're not actually modifying the SVG DOM itself, you're just changing the background color. That way, you could even use images or gradients as background.


Update

As MisterJ mentioned, this feature is sadly not widely supported.

After six years, the support for prefixed use has risen to 97%.