Create and use a cross-browser SVG sprite

My first tutorial ever! A short and simple tutorial about how to create and use SVG sprites in your web project. Making the switch from icon fonts to SVGs can be a little daunting in the beginning but once you get the hang of it you'll see that it's just much much better. Great performance, good browser support and it ensures a high level of maintainability. You can simply add new icons without big hassles. CSS-Tricks has a few good comparisons.

I know that there are tools available to automatically create a sprite, but I'm going to create one by myself step by step to show how it actually comes together.

Get some icons!

Start up Illustrator and create your own icons or get icons from a site like IcoMoon. Click on the IcoMoon App button in the top right corner and go wild! Once you're happy with your choice, click on the Generate SVG & more button in the bottom left corner and download your icon set on the next page. Grab the SVG folder inside the downloaded .zip.

Create the sprite

Create a new SVG and add the following code:

<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20">
  <!-- Symbols -->
  <symbol id="name" viewBox="0 0 0 0">
    <title>Name</title>
    <path d=""></path>
  </symbol>
  <!-- Add icons to document and position to match their corresponding view -->
  <use xlink:href="#name" width="20" height="20" x="0" y="0" />
</svg>

This is the template we are going to use. We can now use our downloaded SVGs and paste them in our sprite.svg. The following things have to be adjusted:

  • svg height
  • Symbol ID
  • Symbol viewBox
  • Symbol Title
  • path
  • use href and y coordinate

Afer adding all our icons the file should now look like this:

<svg xmlns="http://www.w3.org/2000/svg" width="20" height="60">
  <!-- Symbols -->
  <symbol id="home" viewBox="0 0 32 32">
    <title>Home</title>
    <path d="M32 18.451l-16-12.42-16 12.42v-5.064l16-12.42 16 12.42zM28 18v12h-8v-8h-8v8h-8v-12l12-9z"><path>
  </symbol>
	<symbol id="pencil" viewBox="0 0 32 32">
    <title>Pencil</title>
    <path d="M27 0c2.761 0 5 2.239 5 5 0 1.126-0.372 2.164-1 3l-2 2-7-7 2-2c0.836-0.628 1.874-1 3-1zM2 23l-2 9 9-2 18.5-18.5-7-7-18.5 18.5zM22.362 11.362l-14 14-1.724-1.724 14-14 1.724 1.724z"></path>
    </symbol>
	<symbol id="pacman" viewBox="0 0 32 32">
    <title>Pac-Man</title>
    <path d="M30.148 5.588c-2.934-3.42-7.288-5.588-12.148-5.588-8.837 0-16 7.163-16 16s7.163 16 16 16c4.86 0 9.213-2.167 12.148-5.588l-10.148-10.412 10.148-10.412zM22 3.769c1.232 0 2.231 0.999 2.231 2.231s-0.999 2.231-2.231 2.231-2.231-0.999-2.231-2.231c0-1.232 0.999-2.231 2.231-2.231z"></path>
  </symbol>
  <!-- Add icons to document and position to match their corresponding view -->
  <use xlink:href="#home" width="20" height="20" x="0" y="0" />
  <use xlink:href="#pencil" width="20" height="20" x="0" y="20" />
  <use xlink:href="#pacman" width="20" height="20" x="0" y="40" />
</svg>

Great, now we can start using the sprite in our HTML and CSS!

SVG in HTML

Before we can use our icons though, we have to ensure that it'll work in every browser. The JavaScript plugin svg4everybody will allow us to make external SVG sprites work in every browser. After adding the script, we can add our icons with:

<svg>
  <use xlink:href="assets/svg/sprite.svg#home"></use>
</svg>

Note that this won't work local and only on a server. The href points to the sprite you want to use and the hash points to the symbol you want to display. You can now style the SVG with ease in your CSS.

SVG in CSS as background-image

This one's a little bit trickier. To make this less of a headache, I'm using a Sass mixin to easily add the icon as background-image:

$i-sprite: 100% / (3 - 1);

@mixin sprite($nr) {
  background: url('../assets/svg/sprite.svg') no-repeat 50% $i-sprite *
    ($nr - 1) / cover;
}

.icon {
  @include sprite(1);
}

Quick and easy. This will calculate the y coordinate for the background-position depending on the amount of icons in your sprite. The only thing you have to adjust is the variable. The first number in the brackets is the amount of icons in your sprite.

The only downside to this is that you can't change the colour of your icon with CSS. Depending on the project, I usually have a sprite called bg.svg for icons only used as background-image. In the sprite I change the colour by giving the path a fill="#fff" for example (paths are black by default).

Recommended links