Set Fill Color of SVG Background-image
A quick guide explaining how to change the color of an SVG when it’s used as a CSS background-image.
If you want you can jump to the code, else we can explore how this works together.
SVG Background Color Fill Demo
We’ll start with a live demo, focus, hover, or click on the circle below and the background color will animate.
I’ll let the cat out of the bag.
This is just a normal button with an SVG used as a CSS mask
Instead of changing the fill
color of the SVG we change the background-color
of the button. But that shouldn’t spoil the fun as it opens up a world of possibilities but we’ll get to that.
Using An SVG As A CSS Mask
We can see our cool smiley SVG below 😎
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g
stroke-linecap="round"
stroke-width="4"
stroke="rgb(0, 0, 0)"
fill="none"
>
<circle cx="12" cy="12" r="10" />
<path d="M7 11 H17" />
</g>
</svg>
What’s amazing about the timeline we live in is that we can pass the SVG to the CSS url()
function without base64 encoding it or escaping all kinds of characters.
- Prefix the SVG with
data:image/svg+xml,
- Add some structure by ending a line with
\
- Just like that a readable SVG has appeared in our CSS.
Allright, let’s first assign the SVG to the background
property so we can see it, we’ll turn it into a mask in a couple minutes.
button {
/* ...Other styles */
/* Color */
background-color: Crimson;
/* Store the SVG in a variable so it's easy to re-use */
--svg: url('data:image/svg+xml,\
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">\
<g stroke-linecap="round" stroke-width="4" stroke="rgb(0, 0, 0)" fill="none">\
<circle cx="12" cy="12" r="10"/>\
<path d="M7 11 H17"/>\
</g>\
</svg>');
/* Assign the SVG variable */
background-image: var(--svg);
}
button:hover,
button:focus {
background-color: Turquoise;
}
button:active {
background-color: Gold;
}
We can interact with the live demo below to see the SVG has loaded and the styles are correctly applied.
Now it’s time to remove the background
property and assign the --svg
variable to the mask
property.
The black parts of the SVG will be the visible parts of the element and the transparent parts will become invisible.
button {
/* ...Other styles */
/* Chrome, still requires prefix in 2022 */
-webkit-mask: var(--svg);
/* Firefox and Safari */
mask: var(--svg);
}
Tadaa! 🥳
If you have trouble getting the mask to work, a handy trick is to temporarily assign the mask to the background-image
property.
This allows us to visually see where the black and transparent parts of your mask are, this becomes especially useful when building more complex masks.
Any Background Goes
Because we’re masking the button we can use any background style or effect we can think of.
The Complete SVG Background-image Style Code Snippet
You can find the copy button on the right hand side of the code snippet, enjoy!
<button type="button">I'm a cool circle button</button>
<style>
button {
/* Base styles */
display: block;
width: 4rem;
height: 4rem;
border: none;
cursor: pointer;
/* Hide button caption text */
overflow: hidden;
color: transparent;
/* The fill animation */
background-color: Crimson;
transition: background-color 0.2s;
/* Store the SVG in a variable so it's easy to use */
--svg: url('data:image/svg+xml,\
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">\
<g stroke-linecap="round" stroke-width="4" stroke="rgb(0, 0, 0)" fill="none">\
<circle cx="12" cy="12" r="10"/>\
<path d="M7 11 H17"/>\
</g>\
</svg>');
/* Chrome, still requires prefix in 2022 */
-webkit-mask: var(--svg);
/* Firefox and Safari */
mask: var(--svg);
}
button:hover,
button:focus {
background-color: Turquoise;
}
button:active {
background-color: Gold;
}
</style>
Conclusion
We learned a nice trick where we used the CSS mask
property to change the fill color of a SVG when it’s used as a background-image
On top of that we learned that the mask
property is identical to the background
property so we can switch them out to make debugging the mask
image easier.