A modern approach to SVG icons

Posted . Visible to the public. Repeats.

You have some SVG files you want to use as icons on your website. How would you embed them?

Common options are:

  1. Use them with an image: <img src='path-to-icon.svg'>
  2. Embed them inline with <svg>$ICON</svg>
  3. Embed them using CSS and background-image: url(path-to-icon.svg) or even background-image: url(data:$ICON).
  4. Build your own icon font.

All of these have drawbacks:

  • Image and background-image do not allow to recolor the image using CSS.
  • Inline-<svg> are unnecessary work for the server and are not cached.
  • Icon-fonts require complicated setup and are unnecessarily large. In times of http 2+, having fewer request no longer matters.
  • Most solutions do not scale the icon with the font size.

One option that seems to work better is to use the mask CSS feature. The idea is to have an element with a background color in the desired icon color and then use the SVG to mask it, giving it the correct shape. Using SASS, you can write something like this:

// unfortunately, we manually have to list all our icons
$icons: check-mark, loading-indicator, back-arrow

.custom-icon
  --size: 1em
  
  display: inline-block
  width: var(--size)
  height: var(--size)
  background-color: currentcolor
  mask: var(--icon-url) center / contain no-repeat
  
  // only if you do not have auto-prefixer:
  -webkit-mask: var(--icon-url) center / contain no-repeat
  
  // this can probably be done in a better way:
  vertical-align: text-bottom
  margin-bottom: -.1em // depends on the icons
  
  @each $icon in $icons
    &.-#{$icon}
      --icon-url: url(../../images/custom_icons/#{$icon}.svg)

Use it with

<span class="custom-icon -check-mark"></span>

The icon will use the font-size and color of the surrounding block. It works in all relevant browser.

Tobias Kraze
Last edit
Dominik Schöler
License
Source code in this card is licensed under the MIT License.
Posted by Tobias Kraze to makandra dev (2022-12-01 09:50)