# How to Implement Cross-Browser SVG Sprites

In this tutorial I’m going to demonstrate a basic implementation of some SVG icons, how to provide a fallback, and how to turn them into an SVG sprite.

## Basic SVG Implementation

For the purpose of this tutorial I’m going to be using a single page, which will act as a kind of online business card. It will briefly introduce me and display three network profiles relevant to my work.

From the screenshot above you can see that I’m using icons (for Twitter, Dribbble and GitHub) to symbolically reference my network profiles. I downloaded these icons from flaticon, which has a wide range of icons & symbols in both vector and raster formats.

### PNG and SVG

We’re going to begin by using the PNG versions of these icons, for the sake of backward compatibility, then we’ll prepare the SVG versions to use in supporting browsers.

I used Sketch to output my PNG icons, so I’m going to use it again to prepare my icons for SVG usage.

If you look at the screenshot above you’ll notice that I’ve named all my groups and shapes in the left hand panel appropriately (Adobe Illustrator has a similar view in the Layers panel). It’s important to name all your assets correctly, not only to help you remain organised but also for what we’ll be using them for later in this tutorial.

### Exporting SVGs

Now I’ll export the icons as SVGs, which is straightforward with the slicing tool in Sketch. For more information on how this works take a look at Understanding Sketch’s Export Options. I’ll be exporting them as separate files and placing them into the images directory of my project.

Normally, to show an image on your site you’d reference the asset with a src attributed element or something similar:

 1  

However with SVGs there are a number of different ways we can use them within an HTML document. For example, we can use the actual SVG code inline - here’s what that code might look like:

 1   2  

This is one of the icons I exported, in XML format. This code is pretty much just like HTML (it’s a structural format) which means we can slot this straight into the page.

### Adding SVG Inline to the HTML

Let’s begin with the base HTML page which includes the PNG icons with their anchors, and a container:

 1  

Now I’m going to copy and paste the SVG code, however I’m going to ignore the top line which refers to the file’s character encoding and other file attribute details. The HTML document contains that information already so we needn’t duplicate it.

I’ve placed the SVG right above the corresponding PNG icon within the HTML page. For the time being I’m going to wrap the regular PNG image line in a comment tag to stop it appearing next to the SVG version.

### Cleaner SVG

I’m also going to clean up the code within my SVG. Removing the element attributes is optional as most of the pieces I’m removing won’t change how the SVG will act. Here is a before and after if you wish to do the same with yours:

 1  
 1  

Take note of the elements I’ve removed. The <title>, <desc>, and <defs> elements aren’t needed now, but we may need them later on in this tutorial. There are also a few <g> elements which refer to groups, and correspond to the groups created in my Sketch document. By default Sketch places everything inside a page, hence the group element <g id=”Page-1”… . You can remove this as it doesn’t have a use for us (the group within it is more important). Sketch does provide an option to produce cleaner SVGs upon exporting, however there is no harm in cleaning the code up yourself.

The final part of this step is to remove the height and width attributes within the SVG element itself. These will need to be compensated for in my CSS file, as shown below:

 1  
 1 .icon {  2  max-width: 40px;  3  max-height: 40px;  4  transition: .2s;  5  -webkit-filter: drop-shadow(0 1px 0 #11222d);  6 } 

If you’ve followed my steps you should be able to see in the browser a sharp and clean vector version of your graphics.

Tip: Check if the graphic is actually an SVG by zooming in Command-+ when viewing it in the browser. The graphic should stay sharp no matter how far you zoom in.

## Providing a Fallback

If you’re using this for client work you may be wondering what the browser support is like. Inline SVGs work in all browsers except for Internet Explorer 8 (and earlier) and Opera Mini. Can I Use currently says that IE8 is used around 4% globally and Opera Mini around 3%. So in your case you might not need to provide a fallback, however I’m going to demonstrate a solution.

Here is one of my SVG icons within the page, and you’ll notice that my original PNG icon is still in place but wrapped in comments. This PNG image will be our fallback.

First I’ll remove the comments. We now need to move the <img> up and into the <svg> element itself, right after the group containing our actual icon.

Next, I’m going to wrap the <img> in an SVG-specific element called foreignObject. If the browser cannot understand the SVG’s vector information then it will refer to the “foreign object” instead and will proceed to use the <img> within it. We also need to let the browser know that it should opt for the vector version if it supports it. This is what the <switch> element is for, which is what I’ve wrapped both the group and the foreignObject in.

Here’s the updated markup:

If you’ve followed this process and structured your HTML like mine then your graphic should fallback to your original raster image if the browser doesn’t support SVG.

## Creating an SVG Sprite

SVG sprites act pretty much just like image sprites. In their simplest form sprites are a collection of graphical elements combined into one image. Each image is then picked out using CSS and HTML, normally by specifying coordinates and a viewing “window”.

The two main benefits to this are an improved page load time, better workflow, and consistency between the graphical elements on the page. The second and third points apply very well to SVG sprites. Instead of several blocks of SVG code littered throughout our page, we would only have one place to update our SVGs.

To start with I will make a new <svg> element within the <head> element of my page, just before the closing tag. This new SVG will hold all the icons I previously had within the page.

 1   2   3   4   5  David Darnes - Web Designer & Front-end Developer  6   7   10   13  

Next I need to move my icons into it. I don’t need to move the whole SVG, just the group element and its contents. These I can stack within the <svg> element in the head.

 1   2   3   4   5  David Darnes - Web Designer & Front-end Developer  6   7   10   22  

Note: If you're comfortable using Grunt, there’s a plugin will automate the combining of all your separate SVG files.

### Hide!

Now we have all our icons in the head we need to hide them; adding an attribute of display=”none” to the new <svg> will mean all the icons won’t appear at the top of the page.

### Defining Each Icon

Our next step is to define each icon so we can reuse them in the page, which is where the defs element we deleted earlier comes back into play. By using it to wrap all the groups, thus wrapping all my icons, I can state that I want to reuse these elsewhere on  the page.

 1   2   3   4   5  David Darnes - Web Designer & Front-end Developer  6   7   10   24  

### Using the Icons

The icons are now defined but we need a method of using them, which is what the use element is for. The <use> element allows us to take any element within the <defs> element and pull it through to anywhere on our page. The way we pick the element is by using its ID, which is why is was important to name our icons in the initial Sketch document.

Take note of the IDs in the example above and then see how I’m referencing each one with the use element like so <use xlink:href="#twitter-icon"></use>.

If you’ve followed the steps correctly you won’t see any change to how your graphics appear, however you can now reuse them (at whatever size you wish) and apply each one multiple times on the page.

One plus point to using SVG sprites is that your visible page code is much cleaner and can be read more easily by other people working with your code. We can improve on this even more.

Below I’ve changed the <g> elements in my SVG sprite to the symbol element, plus I’ve moved the viewbox attribute from the SVG elements in the page to the new symbol elements.

 1   2   3   4   5  David Darnes - Web Designer & Front-end Developer  6   7   10   24  

Using <symbol> is not only more semantic, at least in my example, but it also saves us repeating the viewbox attribute along with our <svg> and <use> elements. We can bring back the title and desc elements we removed before and use them to improve accessibility on our icons.

Note: Bear in mind that the contents of the <desc> elements are displayed by default in IE7.

 1   2   3   4   5  David Darnes - Web Designer & Front-end Developer  6   7   10   28  

By changing the group element to a symbol we were able to make all of these enhancements. We can remove the <defs> element from the SVG sprite as well, thus making our code even cleaner.

## Conclusion

And there you have it, what started out as mere raster-based icons have now become extremely powerful vector-based icons which can be reused and resized with ease. I hope you enjoyed this tutorial and enjoy playing with SVGs in your next project.