The Best Way to Use SVG Icons in Your Website

Incremental improvements to boost your apps

Evgeniykravtsov
Better Programming
Published in
3 min readJul 6, 2022

Photo by Natalie Chaney on Unsplash

If we want to use SVG images on our website, we can use the image, object, and even iframe tags, SVG sprites, and much more. In this article, we will look at the three of the most popular options — their advantages and disadvantages.

The First and Easiest Way

The most common way I’ve seen to embed SVG into a site is to use the img tag, and insert it into the src attribute. The advantage of this method is that the browser caches this image after the first download. But on the first render, the image will be downloaded after receiving the HTML, which will cause the image to blink. The main disadvantage of this method is that we cannot style the insides of SVG, and only display it in its original form.

Here’s the HTML:

One of the biggest strengths of SVG technology is the ability to manipulate image styles through CSS. This is especially important for icons that you will definitely want to highlight or animate on hover without using additional images.

To be able to recolor SVG via CSS, you need to either insert SVG directly into HTML, that is, “inline” them, or use a separate file, a character sprite. The sprite must also be inserted into the DOM. No other technique allows you to access SVG from CSS. Let’s take a closer look at these techniques.

Inline SVG

Here’s the HTML:

Embedding SVG directly into HTML is both the simplest and most powerful technique in terms of customization and image manipulation.

  1. If the image is large, the whole page will take longer to load.
  2. Using this technique in js frameworks greatly increases the size of the js bundle.
  3. You lose control over loading SVGs, they are no longer external images. You can’t store and cache them separately, neglect loading them on bad connections, and so on.

SVG Sprites

HTML SVG sprite code:

Using an SVG image from sprite:

Images connected via a sprite can be accessed via CSS, although there are limitations. Styles cannot “break through” the shadow boundary, the boundary beyond which the shadow-DOM begins and which is described by the tag.

The good news is that the cascade continues to work. You can change the fill attributes and use currentColor on any property. For most cases with icons, this is more than enough:

Here’s the HTML:

Here’s the CSS:

Cons of this approach:

  • In older browsers (before IE9), the use tag was not supported. But there is a plugin for them, which you can find at this link: https://github.com/jonathantneal/svg4everybody.
  • The sprite will probably become very large, but it’s better than the inline or img tag anyway

To improve performance, you can preload the sprite in the head so that it is ready to use.

Bonus Tip

To autogenerate SVG sprites, use svg-sprite-loader, which helps to implement sprites.

Benefits of svg-sprite-loader:

  • Minimum initial configuration. Most of the options are configured automatically.
  • Runtime for browser. Sprites are rendered and injected into pages automatically, you just refer to images via <svg><use xlink:href="#id"></use></svg>.
  • Isomorphic runtime for node/browser. Can render sprites on the server or in the browser manually.
  • Customizable. Write/extend runtime module to implement custom sprite behaviour. Write/extend runtime generator to produce your own runtime, e.g., React component configured with imported symbol.
  • External sprite file is generated for images imported from css/scss/sass/less/styl/html (SVG stacking technique).

When you require an image, the loader transforms it to SVG <symbol>, adds it to the special sprite storage, and returns a class instance that represents a symbol. It contains id, viewBox and content (id, viewBox and url in extract mode) fields and can later be used for referencing the sprite image. For example:

When the browser event DOMContentLoaded is fired, the sprite will be automatically rendered and injected in the document.body. If custom behaviour is needed (e.g., a different mounting target) default sprite module could be overridden via spriteModule option.

Conclusion

Thank you for reading the article until the end. You can find the complete code for React on GitHub. There are always some ways to make good tools better. Small improvements could help you and your project a lot.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Evgeniykravtsov
Evgeniykravtsov

Written by Evgeniykravtsov

Senior Frontend Developer, web performance enthusiast

Responses (2)

Write a response