How to change the color of SVG icons with CSS only

By Noam S.

March 9, 2020

If you’re here you are probably looking for a simple solution to changing the color of Scalable Vector Graphic (SVG) icons. Seek and you shall find.

This post will show you exactly how to do that. It also contains an SCSS bonus: helping you reduce things to a single line of code.

But is this the optimal way? It depends. If you need to maintain a scalable project and save server requests, then probably not. On a small project, it’s a great solution that will answer most of the needs.

The optimal way is to embed the icon as inline SVG in the code, and to create instances of that icon with the `<use>` tag wherever you wish to do so.

But there’s a problem here. You need time to program and design the code. Codes don’t just rain down upon us from coding heaven. They don’t grow on techie trees. In other words, you will need expert programmers adept at dealing with these issues, who know a lot about SVGs.

If you must deliver quickly, you’re in a bind. You need to work fast and this might not be the best path.

So what are we going to do? Let’s explore the fast option. It has its advantages.

Here is a codepen. In the link you can see the code example. If you don’t like to read long posts just click here: same icon with a different style.


Here is another example of when you change color due to the state change. Here, UX/UI and development meet. Instead of asking the UX/UI designer to send you several assets – one for each state – you can just get one and change its color:



So, let’s get started!

The technique

The technique uses the <div> tag with mask-image and background-color. It is not relevant when:

  • You wish to use an <img/> tag as the html element for the icon since it is not possible to manipulate it with CSS.
  • You implement the SVG inline; in this case there are probably more appropriate techniques.

Div

The html element for the icon will be a div. This will enable us to manipulate the SVG with CSS and get a basic implementation in the html compared to the inline SVG.

Mask-image

We will use a mask for the icon, thus letting the SVG cover the div and give it structure.

Background-color

The icon’s color is obtained from the div’s background-color, by it showing through the SVG’s structure.

Most basic implementation

The most basic implementation is a single class with all needed CSS attributes to apply to the div.

index.html

<div class=”some-icon”></div>

style.css

.some-icon {
  height: 10px;
  width: 10px;
  background-color: $default-text;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  mask-image: url(“/assets/icons/calendar.svg”);
}

Advanced implementation

Here, we define one class for all the common attributes in global.css, even for the uncommon  attributes such as height, width, background-color. For the mask-image, we add a specific class.

index.html

<div class=”svg-icon calendar”></div>

style.css

.svg-icon.calander {
  height: 10px;
  width: 10px;
  background-color: $default-text;
  mask-image: url(“/assets/icons/calendar.svg”);
}

global.css

.svg-icon {
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

Implementation for pros – Mixins!

Mixins allow you to define styles that can be reused throughout your stylesheet. They make it easy to avoid using non-semantic classes like .float-left, and to distribute collections of styles in libraries.
— For Sass official documentation

We’ll create a mixin using SCSS. The mixin will accept commands for all uncommon attributes.

variables.scss

@mixin svg-icon($path, $height, $width, $color ) {
  height: $height;
  width: $width;
  background-color: $color;
  mask-image: url($path);
  background-size: cover;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

index.html

<div class=”calendar”></div>

style.scss

.calendar {
  @include svg-icon(“/assets/icons/calendar.svg”, 20px, 20px,   #818aac);
}

Mixins are included into the current context using the @include at-rule, which is written @include <name> or @include <name>(<arguments…>), with the name of the mixin being included.
— Sass official documentation

To conclude:

What I’ve briefly outlined is a useful and basic implementation designed to keep your assets folder and code as minimal as possible.

Leave a Reply