[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 CSS fill 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!

πŸ‘‹ About the Author

G'day! I am Huy a software engineer based in Australia. I have been creating design-centered software for the last 10 years both professionally and as a passion.

My aim to share what I have learnt with you! (and to help me remember πŸ˜…)

Follow along on Twitter , GitHub and YouTube