HTML & CSS - - By Craig Buckler

How to Use SVG Image Sprites

Despite being scalable, saving bandwidth and an obvious candidate for Responsive Web Design, Scalable Vector Graphics (SVGs) are relatively rare on the web. The reasons?

  • SVGs don’t work in older versions of Internet Explorer — support is only available in IE9+
  • the technology has been around since 1999 — it seems old and unexciting
  • there are fewer vector design tools
  • they’re XML-based which sounds scary to many.

Let’s show some love for SVGs! SVGs are ideal for logos, diagrams and icons. Unlike bitmaps, SVGs can be scaled to any size without losing quality and manipulated using client-side and server-side code. Unlike webfont icons, SVGs can have multiple colors, gradients and even complex filters.

Bitmap Image Sprites

Image sprites have been a good-practice technique for many years. If you require a number of regularly-used graphics, you place them in a single image rather than individual files, e.g.

image sprite

This example contains eight 24×24 icons in a single 192×24 file. The file may offer slightly better compression but the main advantage is it only requires a single HTTP request for all icons to become visible. Loading eight separate icons would take longer since there is more data to download and browsers have a limited number of concurrent requests per domain.

If we require the right-most printer icon, we can use CSS to show the correct image by positioning the background:

	width: 24px;
	height: 24px;
	background: url("sprite.png") -168px 0;

SVG Image Sprites

Is it possible to place multiple SVG images in one file? Absolutely! They also have an advantage over bitmap sprites; you can refer to each image by name rather than calculating pixel positions. As far as I’m aware, this SVG stacks technique was devised by @simurai and @erikdahlstrom although others may have contributed.

We’ll create a very simple SVG with three individual icons — a green circle, red square and blue triangle:

<?xml version="1.0"?>
<svg viewBox="0 0 100 100" xmlns="">

<g class="sprite" id="circle">
	<ellipse cy="50" cx="50" ry="45" rx="45" stroke-width="5" stroke="#00ff00" fill="#00ff00" fill-opacity="0.75" />

<g class="sprite" id="square">
	<rect y="5" x="5" width="90" height="90" stroke-width="5" stroke="#ff0000" fill="#ff0000" fill-opacity="0.75" />

<g class="sprite" id="triangle">
	<path d="M20,7 L92,50 L6,93 z" stroke-width="5" stroke="#0000ff" fill="#0000ff" fill-opacity="0.75" />


Each is stacked on top of the other in a separate g layer which has a class of “sprite” and a unique ID. View the image and you’ll see all three:


Here comes the clever part — you can add a couple of CSS rules to the SVG file which hide all layers except for active layer determined using the :target pseudo selector:

		.sprite { display: none; }
		.sprite:target { display: inline; }

Therefore, if our file is named sprite.xml, we can add a #hash-name to the URL show a specific image, i.e. the URL sprite.xml#circle will display the layer with the ID “circle” at any dimensions you choose.

View the SVG sprite demonstration page…

There are a number of methods you can use to add SVG sprites to your page: object/embed, an iframe, an img tag or a CSS background. The demonstration shows all techniques and they work well in Internet Explorer 9+, Firefox and Opera 12 and below.

Unfortunately, the img and CSS background methods fail in the Webkit/Blink browsers — Chrome, Safari and Opera 15+. There are various on-going discussions but there is no guarantee SVG stacks will ever be fully supported. That’s a shame because the technique seems so useful.

Unless Webkit can be persuaded to join the SVG stacks party, object or embed is the best cross-browser solution, e.g.

<object type="image/svg+xml" width="100" height="100" data="sprite.svg#circle"></object>

This also has the advantage that you can directly address and update the SVG sprite using DOM scripting.