Rendering modes

This tutorial is part of Iconify Icon web component tutorial.

Web component supports several icon rendering modes.

Modes

There are 4 modes supported by web component:

  • "svg": renders <svg> element.
  • "style": uses either "bg" or "mask" mode, depending on icon palette.
  • "bg": renders <span> element with icon as background image. Usable only for icons that have palette.
  • "mask": renders <span> element with icon as mask image. Usable only for icons that do not have palette.

Demo showing 2 icons (one monotone, one with palette) rendered with 4 modes:

svg:

style:

bg: monotone icon shown as black

mask: icon with palette loses color

Code samples

What do these modes actually look like in DOM?

Examples for mdi:home (used in modes demo above) icon:

svg mode:
<svg
   xmlns="http://www.w3.org/2000/svg"
   width="1em"
   height="1em"
   viewBox="0 0 24 24"
>

   <path fill="currentColor" d="M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5Z"></path>
</svg>
bg mode:
<span
   style="
       --svg: url('data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'24\' height=\'24\' viewBox=\'0 0 24 24\'%3E%3Cpath fill=\'currentColor\' d=\'M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5Z\'/%3E%3C/svg%3E');
       width: 1em;
       height: 1em;
       background-color: transparent;
       background-image: var(--svg);
       background-repeat: no-repeat;
       background-size: 100% 100%;
   "

>
</span>
mask mode:
<span
   style="
       --svg: url('data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'24\' height=\'24\' viewBox=\'0 0 24 24\'%3E%3Cpath fill=\'currentColor\' d=\'M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5Z\'/%3E%3C/svg%3E');
       width: 1em;
       height: 1em;
       background-color: currentcolor;
       -webkit-mask-image: var(--svg);
       -webkit-mask-repeat: no-repeat;
       -webkit-mask-size: 100% 100%;
       mask-image: var(--svg);
       mask-repeat: no-repeat;
       mask-size: 100% 100%;
   "

>
</span>

Why not just render SVG?

You are probably wondering, why is it even needed? Isn't <svg> enough?

Rendering icon as <svg> works for most icons, but it does not always work for icons that use SVG animations.

SVG animations cannot start until document is ready. It might seem like a small thing, but animations not rendering quickly enough can cause bad user experience. This issue can be caused by small things, such as statistics script failing to load or ad code loading slowly. If at least one server that page is loading resources from is unreachable, it might break all animated SVGs on page. Async and defer attributes do not help. Issue can even be caused by script in an iframe.

Animation delay demo

Below is an <iframe> that shows icon rendering issue. It contains animated icon, rendered as <svg> and as background image. Both icons render instantly, but animation in <svg> does not start for few seconds because document is still loading.

To make things worse, this demo, which is in <iframe>, affects the main document. Logo on this page is rendered as <svg> and it contains animations. Refresh this page to see how slow script in a frame prevents SVG animations in unrelated icons in the main document.

Backgrounds and masks

Background images cannot use currentColor, but they do keep icon's palette, so icons with palette can be rendered as background image.

But what to do if icon uses currentColor? Solution is to use icon as mask and set background color to currentColor.

Combination of background and mask images make it possible to use almost all SVGs as URLs. The only icons that cannot be rendered correctly are icons that mix currentColor and hardcoded palette.

See Icons in Pure CSS article by Anthony Fu that explains it in more details.

SVG animations

When icon has animations, animations start immediately if it is rendered as mask or background, solving animation delay issue mentioned few sections above.

However, there is another issue: browser cache in Chrome. Image is rendered as URL. If URL is already in browser cache, Chrome does not restart animation. That means consequent renders of the same animated icons can bug out.

So there are issues with SVG animations when used as background or mask too. Web component solves it by adding random commented out content to icon, which causes it to bypass browser cache.

Which mode to use?

Web component will automatically use best mode:

  • If icon has SVG animations, "style" to render animations immediately.
  • Otherwise "svg", which renders slightly faster in most browsers.