Proper websites, done properly

Inline SVG versus CSS background images

3 minute read time / 414 words

It's an accessibility and performance consideration - so which to choose, and where?

There are several pros and cons for using inline SVGs over CSS background images:

  • Each inline SVG means one less server request to complete the loading of your page
  • Inline SVGs can have CSS transitions applied to them, such as changing the fill or stroke colour nicely.
  • Because the image is in the HTML payload, there's no delay in rendering the image. The browser doesn't have to wait for the CSS and the image before it's done.
  • Inflates your HTML payload size
  • If you need to change an image, you'll have to replace every inline instance of it
  • Muddies the water if you like to stick to the principle of separating style from content.

On the other hand, using CSS background images:

  • Style is separated from content
  • Easier maintenance of images in the future - change the file for a new one once to get it appear everywhere it's used
  • Flexibility of being able to change images at different breakpoints or container sizes, or for different colour themes.
  • Each background image is one extra server request to fetch
  • Can cause Largest Contentful Paint (LCP) issues because before the image appears, the browser has to fetch the document, your stylesheet, parse them both and then fetch and render the image too.

In general terms - anything 'critical' to the page load, such as your site logo, any icons that might appear in the head for all users on mobile, tablet or desktop should be under consideration for being an inline SVG.

It'll prevent LCP problems in your Core Web Vitals checks, and it'll make your page load feel snappier.

Anything further down the page, or anything that needs additional flexibility - you can choose to use a CSS background image, or if you're happy to keep increasing your HTML size, feel free to keep on using those inline SVGs.

If you're using inline SVGs for things like a site logo, or in other areas where traditionally you might have used a CSS text replacement technique to keep things accessible for screenreaders, you should ensure that anywhere an inline SVG sits, it has appropriate hidden screenreader text to accompany it.

<a href="/" class="site-logo">
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 255 60" class="icon">
        <path fill="#fff" d="....." />
    </svg>
    <span class="vh">My Site Name</span>
</a>
.vh {
    position: absolute;
    overflow: hidden;
    clip: rect(0 0 0 0);
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
}