It’s safe to say that scalable vector graphics (SVG) has grown increasingly popular in recent years, and for good reason. The standard offers a truly resolution-independent technique for presenting graphics that is well supported in browsers today. There is no reasonable excuse to avoid using SVG for vector graphics on the web (with a PNG fallback, primarily for IE < 9 and older Android).
Why not just use an icon font?
There are many answers to this question and it has already been covered extensively in other articles. The main problem with icon fonts is down to accessibility. Most screen readers or assistive devices will read aloud the text inserted via CSS, which in most cases are made up of Unicode characters. They don't give any descriptive text to the user of what that icon is. This can be a big problem if your main navigation elements contain only icons and no text alternative. It also causes problems for dyslexic users where the majority change the typeface which in turn breaks the icons. Developers also face problems with positioning limitations. Getting the icon to align vertically against text across multiple browsers can be a challenge.
Once you have an effective SVG workflow in place, you'll wonder why you used anything else. The following section is a deep-dive into the various implementations available to us, along with their individual fallback methods for those of you supporting IE8 and older Android.
When using SVG images in their most basic form, we can start off with what we're used to: a simple image element pointing the src attribute to our SVG.
Alternatively, you can do this through CSS by hiding the image tag and applying a background-image to its parent element.
With this technique, browsers that don’t support SVG will face two HTTP requests, which can have performance implications.
CSS Background Images
Similar to using an image element, we can also use an SVG image as a background-image.
When using a background-image, it’s important to note you have to set the background-size property, otherwise we would only see the upper left hand corner of our SVG image.
Using SVG as background images have their own set of browser support. With that said, the fallback method is very much the same as our image element above.
As we're replacing the background-image with a supported format, only one HTTP request is made, instead of the two requests above.
The techniques above are good to go and will work. However, they do have one problem: they don’t use SVG to its full potential. SVG images have a whole host of other features that you’ll probably want to take advantage of.
Using Inline SVG Elements
Simply open the SVG file in your text editor, copy the code and paste it directly into your HTML document.
Now we can control the contents with CSS. SVG have their own unique set of properties, a popular one being the fill property to change the colour.
Similar to the background-image technique, we also need to specify the size of the SVG using the width and height properties.
A disadvantage of this method is that the browser can’t cache the image. So when using it in multiple locations, even though it’s the same image, it will make another HTTP request which isn’t ideal. Also, maintaining inline SVG code across your site can be a pain.
It is the easiest way to manipulate SVG, but as you can see it has its disadvantages. This is where SVG definitions come to save the day. These can be cached and are easier to maintain – keep reading below.
The easiest solution is to provide a PNG alternative through the CSS background-image property – providing our SVG inline element has a class applied, which in our case it does:
This allows us to define our graphical objects from within an SVG and then render the elements out onto the page using the use element. In essence, we load one SVG and then reference to a definition in that SVG every time we need to use an inline SVG. Note it's recommended that the SVG is placed above the use insertions – otherwise they may not display in some browsers.
Once the browser has rendered the HTML, we simply make a reference to that SVG with the use element. The href value is used to reference the id from the SVG.
This does a pretty good job, but we can do one better. Don’t forget that the HTML parser will have to trawl through the contents of that SVG before any content is reached each time the page loads, even if the site has HTML caching enabled. It’s not a brilliant technique.
A more efficient approach is to ajax the SVG, and inject it into the DOM. This will take advantage of browser caching and give the HTML parser a bit of a break.
In your HTML document, you use the exact same method as above, just without the SVG – this is now getting ajaxed in.
There are multiple methods of using SVGs. I've only covered a handful that I find works best for me. I haven't covered areas such best practices for creating your SVG along with optimisation, or automating SVG sprite generation. There are already great articles out there for these topics which I've provided links to below.
I would recommend trying out some of these approaches and see what fits you best. If you don't have to provide fallbacks, things get a lot easier as it can get complicated quickly when supporting these browsers.
- SVG on the web
- SVG sprite creation techniques
- Grunt SVG store
- Caching SVG sprite in localstorage