[Fix] CSS SVG fill not working
We can change the color of a SVG path or element with the fill property. However theres many ways to get it wrong. This post goes over the fixes.
Dec 15, 2022 | Read time 8 minutesπ Table of contents
Introduction
While working with SVGs in one of my web designs, I noticed setting the fill
property did not work. I wanted to fill my SVG with a color!
If you are having issues with the fill property of an SVG element in CSS, There are a few steps you can take to fix the issue with SVG fill not working in CSS:
- Check that the syntax with the
fill
property is correct - Make sure to use inline SVGs instead of external
- If you are using
url()
method - make sure to encode values such as#
in hex colors - Check if there is a
fill
attribute in the SVG itself. When there is a fill attribute, the CSSfill
property will not work!
1. Check that the syntax with the fill
property is correct
Usually to color a SVG shape, we can use the fill to set the color. There are several ways to do this, so it could lead to mistakes and making it
not work as expected. Generally, there are 4 ways to do this:
a. Using the fill
attribute on the SVG element. In the below we add fill="blue"
to the Apple logo.
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="blue">
<path d="M16.46 5.79l.3.01a5.6 5.6 0 0 1 4.38 2.38c-.1.07-2.62 1.53-2.59 4.57.04 3.63 3.19 4.84 3.22 4.86-.02.08-.5 1.72-1.66 3.41-1 1.46-2.04 2.92-3.67 2.95-1.6.03-2.13-.96-3.96-.96-1.84 0-2.42.93-3.94.99-1.57.06-2.78-1.58-3.78-3.04-2.07-2.98-3.64-8.42-1.53-12.1a5.87 5.87 0 0 1 4.97-3c1.55-.03 3.01 1.04 3.96 1.04.95 0 2.73-1.29 4.6-1.1zM16.78 0a5.3 5.3 0 0 1-1.25 3.83 4.46 4.46 0 0 1-3.56 1.7 5.03 5.03 0 0 1 1.27-3.71A5.38 5.38 0 0 1 16.78 0z"/>
</svg>
b. Using embedded CSS. We can βembedβ the CSS inside our SVG element using the <defs>
tag (definitions). This just means that we want to add elements that are not
part of the SVG. In our case this is the styling:
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24">
<defs>
<style><![CDATA[
#myPath {
stroke: black;
fill: red;
}
]]></style>
</defs>
<path id="myPath" d="M16.46 5.79l.3.01a5.6 5.6 0 0 1 4.38 2.38c-.1.07-2.62 1.53-2.59 4.57.04 3.63 3.19 4.84 3.22 4.86-.02.08-.5 1.72-1.66 3.41-1 1.46-2.04 2.92-3.67 2.95-1.6.03-2.13-.96-3.96-.96-1.84 0-2.42.93-3.94.99-1.57.06-2.78-1.58-3.78-3.04-2.07-2.98-3.64-8.42-1.53-12.1a5.87 5.87 0 0 1 4.97-3c1.55-.03 3.01 1.04 3.96 1.04.95 0 2.73-1.29 4.6-1.1zM16.78 0a5.3 5.3 0 0 1-1.25 3.83 4.46 4.46 0 0 1-3.56 1.7 5.03 5.03 0 0 1 1.27-3.71A5.38 5.38 0 0 1 16.78 0z"/></svg>
c. The last sytax option to check is use of external or inline CSS. For external CSS, make sure that you have referenced the files correctly.
For inline CSS, make sure that we are targeting the correct element.
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" style="fill:red">
<path d="M16.46 5.79l.3.01a5.6 5.6 0 0 1 4.38 2.38c-.1.07-2.62 1.53-2.59 4.57.04 3.63 3.19 4.84 3.22 4.86-.02.08-.5 1.72-1.66 3.41-1 1.46-2.04 2.92-3.67 2.95-1.6.03-2.13-.96-3.96-.96-1.84 0-2.42.93-3.94.99-1.57.06-2.78-1.58-3.78-3.04-2.07-2.98-3.64-8.42-1.53-12.1a5.87 5.87 0 0 1 4.97-3c1.55-.03 3.01 1.04 3.96 1.04.95 0 2.73-1.29 4.6-1.1zM16.78 0a5.3 5.3 0 0 1-1.25 3.83 4.46 4.46 0 0 1-3.56 1.7 5.03 5.03 0 0 1 1.27-3.71A5.38 5.38 0 0 1 16.78 0z"/>
</svg>
2. Make sure to use inline SVGs instead of external
One issue with using fill in CSS that comes up is when using SVG as an external. Lets say we have an external SVG file named apple.svg
. Now we want to include that in our
HTML like so (using the <img>
tag):
...
<body>
<img id="mySVG" src="apple.svg" alt="My Happy SVG" />
</body>
...
Now when we try to apply the fill
CSS style, it will NOT work.
#mySVG {
fill:red;
}
One option to fix this is: we need to add our SVG as a inline element, instead of loading it externally:
...
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" id="mySVG">
<path d="......"/>
</svg>
</body>
...
/* The following CSS will then work */
#mySVG {
fill:red;
}
Tip: If you really need to use external SVG files, can use the
currentColor
technique
If we do not want to litter our HTML with a bunch of nasty looking inline SVGs, we can use the currentColor
technique.
For this, we just need to modify our SVG to have fill:currentColor
.
Then in our CSS, we can target this, by changing the color
property.
As an example, consider the following SVG of the Apple logo. We added a fill attribute fill="currentColor"
:
<svg id="mySVG"
width="48"
height="48"
viewBox="0 0 24 24" fill="currentColor" > <!-- βοΈ Add the currentColor variable -->
<path d="M16.46 5.79l.3.01a5.6 5.6 0 0 1 4.38 2.38c-.1.07-2.62 1.53-2.59 4.57.04 3.63 3.19 4.84 3.22 4.86-.02.08-.5 1.72-1.66 3.41-1 1.46-2.04 2.92-3.67 2.95-1.6.03-2.13-.96-3.96-.96-1.84 0-2.42.93-3.94.99-1.57.06-2.78-1.58-3.78-3.04-2.07-2.98-3.64-8.42-1.53-12.1a5.87 5.87 0 0 1 4.97-3c1.55-.03 3.01 1.04 3.96 1.04.95 0 2.73-1.29 4.6-1.1zM16.78 0a5.3 5.3 0 0 1-1.25 3.83 4.46 4.46 0 0 1-3.56 1.7 5.03 5.03 0 0 1 1.27-3.71A5.38 5.38 0 0 1 16.78 0z"/>
</svg>
Now in our CSS, we can use the following to color
property to change the fill color to red:
#mySVG {
color:red; /* βοΈ Fill will work now. */
}
3. If you are using url()
method - make sure to encode values such as #
in hex colors
With SVGs, we can include them in our CSS background
property like below:
div {
background: url("data:image/svg+xml;utf8,
<svg xmlns='http://www.w3.org/2000/svg'>
<path fill='#FF0000' /* β THIS WILL NOT WORK ! */
d='M 0,10 H 20 L 10,0 Z' />
</svg>");
}
The problem with the above is that our fill
attribute is using a HEX value #FF0000
. For url() to work, we need to encode the string. In this case #
becomes %23
So the fix will be changing to fill='%23FF0000'
div {
background: url("data:image/svg+xml;utf8,
<svg xmlns='http://www.w3.org/2000/svg'>
<path fill='%23FF0000' /* βοΈ FIXED ! */
d='M 0,10 H 20 L 10,0 Z' />
</svg>");
}
4. Check if there is a fill
attribute in the SVG itself.
Be careful of style conflicts when using the fill
attribute. Styles will be applied by the following order:
- inline CSS styles
- fill HTML attribute on the SVG element
- embeded fill styling inside the
<defs>
tag - external CSS
So if you already have set a fill value on the SVG element, the CSS that is external with fill values will not work! They will be overwritten!
Browser support
- Support for this is wide across modern browsers. Only issues comes up when you need to support older browsers like IE.
- IE9-11 & Edge donβt properly scale SVG files and limited support on animations!
Summary
In this post, I went over a few reasons why using SVG fill is not working for our CSS.
There are various reasons since there so many ways to fill a SVG path/ element.
Some things to look out for include: checking if we got the right syntax, checking that there are no style conflicts or being overwritten, verify that we encode urls when loading SVGs with the url() method!