How to use SVG in CSS

If you are migrating from font, you might be used to adding icons by adding pseudo elements to stylesheet, something like this:

.test:after {
   content: '\f015';
   font-family: SomeIconFont;
}

It can be done with SVG too!

Usage

There are several ways to use SVG in CSS:

  • Content of pseudo-selector.
  • Background image.
  • Mask image, combined with background color set to currentColor.

First 2 methods can be used with icons that have hardcoded palette. If you use it with monotone icon that uses currentColor, it will be rendered black.

Last method can be used with monotone icons. Icon shape will be used as mask, which will be filled with currentColor, so it behaves similar to icon font, following text color.

Monotone icon (hover to change color):

Mask:

Icons with palette (hover does not change icon color):

Content:
Background:

HTML:
<p class="demo-notice">Monotone icon (hover to change color):</p>
<p class="demo-hover-color">Mask: <span class="mask-test"></span></p>
<p class="demo-notice">
   Icons with palette (hover does not change icon color):
</p>
<p class="demo-hover-color">
   Content: <span class="pseudo-test"></span>
   <span class="pseudo-test pseudo-test--2"></span><br />
   Background: <span class="background-test"></span>
   <span class="background-test background-test--2"></span><br />
</p>
Stylesheet:
/* Common styles for mask and background */
.background-test,
.mask-test {
   display: inline-block;
   width: 1em;
   height: 1em;
}

/* Pseudo element demo */
.pseudo-test:after {
   content: url('https://api.iconify.design/fluent-emoji-flat/alarm-clock.svg?height=16');
}
.pseudo-test--2:after {
   content: url('https://api.iconify.design/bi/bell-fill.svg?height=16&color=%23007267');
}

/* Background demo */
.background-test {
   background-image: url('https://api.iconify.design/fluent-emoji-flat/alarm-clock.svg');
   background-repeat: no-repeat;
   background-size: 100% 100%;
}
.background-test--2 {
   background-image: url('https://api.iconify.design/bi/bell-fill.svg?color=%23007267');
}

/* Mask demo */
.mask-test {
   background-color: currentColor;
   -webkit-mask-image: url('https://api.iconify.design/bi/bell-fill.svg');
   mask-image: url('https://api.iconify.design/bi/bell-fill.svg');
   -webkit-mask-repeat: no-repeat;
   mask-repeat: no-repeat;
   -webkit-mask-size: 100% 100%;
   mask-size: 100% 100%;
}

Below is detailed explanation of each method.

Content in pseudo-selector

You can use SVG as content in pseudo-selector:

/* SVG as pseudo element's content */
.test:after {
   content: url('https://api.iconify.design/bi/bell-fill.svg?height=16');
}

This method inserts SVG as external image, similar to <img />.

Differences from other methods:

  • Can be used for images with hardcoded palette.
  • currentColor is ignored. You need icon to have hardcoded color, otherwise image will be black.
  • Pseudo element is scaled to image dimensions. You should specify image dimensions in parameters when loading it from API.

Background

You can use SVG as background image:

/* SVG as pseudo element's background image */
.test:after {
   content: '';
   width: 1em;
   height: 1em;
   display: inline-block;
   background: url('https://api.iconify.design/bi/bell-fill.svg') no-repeat
       center center / 100% 100%;
}

/* SVG as background image */
.test {
   width: 1em;
   height: 1em;
   display: inline-block;
   background: url('https://api.iconify.design/bi/bell-fill.svg') no-repeat
       center center / 100% 100%;
}

Differences from other methods:

  • Can be used for images with hardcoded palette.
  • currentColor is ignored. You need icon to have hardcoded color, otherwise image will be black.
  • You need to resize element (or pseudo element) to fit image.

Mask

Mask, combined with background color set to currentColor, can be used to render monotone icons that use currentColor as icon color.

/* SVG as pseudo element's mask image */
.test:after {
   content: '';
   width: 1em;
   height: 1em;
   display: inline-block;
   background-color: currentColor;
   -webkit-mask-repeat: no-repeat;
   mask-repeat: no-repeat;
   -webkit-mask-size: 100% 100%;
   mask-size: 100% 100%;
   -webkit-mask-image: url('https://api.iconify.design/bi/bell-fill.svg');
   mask-image: url('https://api.iconify.design/bi/bell-fill.svg');
}

/* SVG as mask image */
.test {
   width: 1em;
   height: 1em;
   display: inline-block;
   background-color: currentColor;
   -webkit-mask-repeat: no-repeat;
   mask-repeat: no-repeat;
   -webkit-mask-size: 100% 100%;
   mask-size: 100% 100%;
   -webkit-mask-image: url('https://api.iconify.design/bi/bell-fill.svg');
   mask-image: url('https://api.iconify.design/bi/bell-fill.svg');
}

Differences from other methods:

  • Cannot be used for images with hardcoded palette because color is removed.
  • currentColor is used to fill mask, so it can be used for monotone images without specifying color.
  • You need to resize element (or pseudo element) to fit image.

Demo

Why monotone icon cannot be used as background or content? Why icons with multiple colors cannot be used as mask? See demos below, which show what happens if you use icon incorrectly.

Various usages of monotone icon:

Icons below use "currentColor" (hover to change color):

Content: (always black)
Background: (always black)
Mask:

HTML:
<p class="demo-notice">
   Icons below use "currentColor" (hover to change color):
</p>
<p class="demo-hover-color">
   Content: <span class="pseudo-test"></span> <small>(always black)</small><br />
   Background: <span class="background-test"></span> <small>(always black)</small
   ><br />
   Mask: <span class="mask-test"></span>
</p>
Stylesheet:
/* Common styles for mask and background */
.background-test,
.mask-test {
   display: inline-block;
   width: 1em;
   height: 1em;
}

/* Pseudo element demo */
.pseudo-test:after {
   content: url('https://api.iconify.design/bi/bell-fill.svg?height=16');
}

/* Background demo */
.background-test {
   background-image: url('https://api.iconify.design/bi/bell-fill.svg');
   background-repeat: no-repeat;
   background-size: 100% 100%;
}

/* Mask demo */
.mask-test {
   background-color: currentColor;
   -webkit-mask-image: url('https://api.iconify.design/bi/bell-fill.svg');
   mask-image: url('https://api.iconify.design/bi/bell-fill.svg');
   -webkit-mask-repeat: no-repeat;
   mask-repeat: no-repeat;
   -webkit-mask-size: 100% 100%;
   mask-size: 100% 100%;
}

Various usages of icon with hardcoded palette:

Icons below have hardcoded palette:

Content:
Background:
Mask: (all shapes are filled with same color, making icon unusable)

HTML:
<p class="demo-notice">Icons below have hardcoded palette:</p>
<p class="demo-hover-color">
   Content: <span class="pseudo-test"></span><br />
   Background: <span class="background-test"></span><br />
   Mask: <span class="mask-test"></span>
   <small>(all shapes are filled with same color, making icon unusable)</small>
</p>
Stylesheet:
/* Common styles for mask and background */
.background-test,
.mask-test {
   display: inline-block;
   width: 1em;
   height: 1em;
}

/* Pseudo element demo */
.pseudo-test:after {
   content: url('https://api.iconify.design/fluent-emoji-flat/alarm-clock.svg?height=16');
}

/* Background demo */
.background-test {
   background-image: url('https://api.iconify.design/fluent-emoji-flat/alarm-clock.svg');
   background-repeat: no-repeat;
   background-size: 100% 100%;
}

/* Mask demo */
.mask-test {
   background-color: currentColor;
   -webkit-mask-image: url('https://api.iconify.design/fluent-emoji-flat/alarm-clock.svg');
   mask-image: url('https://api.iconify.design/fluent-emoji-flat/alarm-clock.svg');
   -webkit-mask-repeat: no-repeat;
   mask-repeat: no-repeat;
   -webkit-mask-size: 100% 100%;
   mask-size: 100% 100%;
}

Iconify API

You can use Iconify API to dynamically generate images for stylesheet.

See Iconify API documentation.