In a world where we’re focusing so heavily on mobile phone resolutions, pixel densities and Apple’s much coined Retina Display, the choice of how you display graphical elements on your page can be the difference between a crisp, sharp user experience, or one that’s a little rough around the edges.

Largely on the web you would be restricted to using rasterised graphics - file formats like JPG, GIF or PNG. Those are fine in some cases, however to get those crisp logos, buttons and interface elements, you’ll want to look towards vector.

The difference between enlarging a PNG (left) and SVG (right)

The difference between enlarging a PNG (left) and SVG (right)

You may have already heard of SVG (Scalable Vector Graphics) - these files are made up of path ‘data’ that gives a smooth display no matter how large - or small - you want to make the image.

SVGs then make an obvious choice for use on websites, they’ll stay crisp and sharp no matter the latest, flashiest, pixel-populated device that money can buy. Plus they’ll typically be a much, much smaller filesize than a rasterised equivalent.

When opting to use SVGs for the Metlink website, we discovered that there’s a few things to consider when using SVGs online. Let’s cover some of the basics:

At the simplest, you can opt to use an SVG file in place of a GIF or PNG in a simple image tag:

<img src="logo.svg" />

Success it works! This is by far the simplest way to insert a SVG. It will insert the graphic at the original size that it was saved at. You can assign a width to it and it'll scale without losing any quality. However, this won't work in Internet Explorer 8 and below as they do not support embedding SVGs.

The solution then, for older browser support is to provide a fallback file:

<img src="logo.svg" onerror="this.src='logo.png'; this.onerror=null;" />

When browsers that don’t support SVG encounter this image, they'll trigger the onerror property and replace the src with logo.png.

So we’ve now got cross-browser support for embedding SVG files, with a fallback for those older browsers that don’t support it.

The second major benefit to using SVG outside of their vector properties, is that you can directly manipulate the vector paths without having to go back and save a new version of the file. Consider the following code that is generated for an SVG:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="43px" height="43px" viewBox="0 0 43 43" enable-background="new 0 0 43 43" xml:space="preserve">
	<g>
		<path fill="#FF6E01" d="M21.458,3.308c-10.079,0-18.25,8.171-18.25,18.25c0,10.079,8.171,18.25,18.25,18.25s18.25-8.17,18.25-18.25
		C39.707,11.479,31.537,3.308,21.458,3.308z M25.282,34.802l-0.569-3.48c4.056-1.392,6.972-5.235,6.972-9.763
		c0-5.7-4.621-10.322-10.321-10.321c-5.701,0-10.321,4.621-10.321,10.321c0,3.915,2.18,7.32,5.39,9.069
		c0.007,0.004,0.014,0.008,0.021,0.012l6.025-9.081l-1.073,12.44c0,0-0.005,0-0.006,0l-0.119,1.368
		c-2.471-0.015-4.786-0.68-6.788-1.829c-4.146-2.384-6.94-6.854-6.939-11.979c0-7.626,6.183-13.81,13.81-13.81
		c7.628,0,13.811,6.184,13.811,13.81C35.174,27.824,31,33.111,25.282,34.802z"/>
	</g>
</svg>

SVGs are relatively simple in their structure, opting for a XML document to describe the paths and shapes that make up the object. In our case the shape in this SVG is made up of one path element.

The web likes XML. In fact, you can take this XML and insert into directly into a webpage and it’ll render the SVG. You can style the object elements directly with CSS:

<style type="text/css">
svg path{
	fill: blue;
}
</style>

Voila, now the SVG is blue. You can re-use the same SVG file multiple times and colour it accordingly.

If you do opt to embed the XML from the SVG file directly into your website, you’ll need to consider the fact that if you ever update your SVG file, you’ll need to go through and update all places that you’ve embedded the XML.

When using the <img> tag we could supply a fallback image with the onerror property, when embedding the SVG XML directly, you can achieve a similar result with foreignObject

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="43px" height="43px" viewBox="0 0 43 43" enable-background="new 0 0 43 43" xml:space="preserve">
	<switch>
		<g>
			<path fill="#FF6E01" d="M21.458,3.308c-10.079,0-18.25,8.171-18.25,18.25c0,10.079,8.171,18.25,18.25,18.25s18.25-8.17,18.25-18.25
			C39.707,11.479,31.537,3.308,21.458,3.308z M25.282,34.802l-0.569-3.48c4.056-1.392,6.972-5.235,6.972-9.763
			c0-5.7-4.621-10.322-10.321-10.321c-5.701,0-10.321,4.621-10.321,10.321c0,3.915,2.18,7.32,5.39,9.069
			c0.007,0.004,0.014,0.008,0.021,0.012l6.025-9.081l-1.073,12.44c0,0-0.005,0-0.006,0l-0.119,1.368
			c-2.471-0.015-4.786-0.68-6.788-1.829c-4.146-2.384-6.94-6.854-6.939-11.979c0-7.626,6.183-13.81,13.81-13.81
			c7.628,0,13.811,6.184,13.811,13.81C35.174,27.824,31,33.111,25.282,34.802z"/>
		</g>
		<foreignObject>
			<img src="logo.png" />
		</foreignObject>
	</switch>
</svg>

Why not combine the two methods and get the best of both worlds? Let's use the <img> tag to embed an external SVG file so that it always shows our latest changes to the file (and we don’t bloat our document with a lot of repeated XML), with an onerror fallback for older browsers. We’ll then get jQuery to come along and replace our <img> tag with the inline XML on-the-fly for supported browsers so that we can access and style it with CSS:

Our HTML:

<img src="logo.svg" class="svg-replace svg-blue" onerror="this.src='logo.png'; this.onerror=null;" />

Our JavaScript:

<script type="text/javascript">
$(document).ready(function() {
	embedSVGs()
});

embedSVGs = function(){

	jQuery('img.svg-replace').each(function(){
		var img = jQuery(this);
		var imgID = img.attr('id');
		var imgClass = img.attr('class');
		var imgURL = img.attr('src');
	
		jQuery.get(imgURL, function(data) {
			// Get only the  tag
			var svg = jQuery(data).find('svg');
	
			// Keep any IDs used on the image tag
			if(typeof imgID !== 'undefined') {
				svg = svg.attr('id', imgID);
			}
	
			// Keep any classes used on the image tag
			if(typeof imgClass !== 'undefined') {
				svg = svg.attr('class', imgClass+' replaced-svg');
			}
	
			// Add preserveaspectratio
			svg = svg.attr('preserveaspectratio','xMidYMid meet');
	
			// Remove any invalid XML tags as per http://validator.w3.org
			svg = svg.removeAttr('xmlns:a');
	
			// Always ensure embedded SVGs have a max-height CSS property set
			// We set 100% width/height here to ensure scaling works
			svg = svg.attr('width','100%');
			svg = svg.attr('height','100%');
	
			// Replace image with new SVG
			img.replaceWith(svg);
		 }, 'xml');
	});
}
</script>

Our CSS:

<style type="text/css">
.svg-blue path{
	fill: blue;
}
</style>

This is the method that we employ on many of our projects to utilize the benefits of SVG. We opted for these crisp, sharp graphics for interface elements on the Metlink website, ensuring that users across all device types get a high quality experience.

This just scratches the surface of the capabilities of SVG. With CSS you can do much more than colour the graphic - in fact we’ve opted for some additional functionality in our very own logo at the top of this page.