SVG for Mobile in the Real World

SVG seems to be a highly contested subject right now. You have the people that think it’s the hottest thing out there and should be used almost exclusively, and the people that say that it’s just not useful or ready for prime time. If you came here hoping to settle that debate you might be disappointed. I disagree with both of them. The truth is that SVG is amazing but it has some drawbacks too. Hopefully my story will help you see where and when you can use it, and maybe even help you avoid some of the pitfalls.

A little while back we launched a new mobile site for VentureBeat. Mobile development has always had plenty of struggles, but the new high-res screens have added a new one. Common practice is to use @media queries with the browser-specific -webkit-min-device-pixel-ratio to change out your background image to a larger one for these high-density displays:

#logo {
	background-image: url( ../images/logo.png );
}
@media only screen and (-webkit-min-device-pixel-ratio: 2)  {
	#logo {
		background-image: url( ../images/logo-2x.png );
	}
}

This works and even better it’s easy to understand. So what’s the bid deal? Well, it turns out there are several drawbacks:

  1. You need two of each image that are no different except for size.
  2. It’s not very future-proof. How long before there’s a pixel ratio of 4?
  3. These higher-resolution devices don’t necessarily have better connection speeds, so larger images still take a while to download.
  4. Zooming. When you zoom in, even the larger image will eventually suffer from pixelation.

Having additional images is annoying but storage is cheap. I could deal with this one. On the web nothing is future-proof. I like to be as future-proof as possible, but again this one seems like a tough argument to make. The last two issues, however, are killer. Larger images look nice, but take too long to download. Additionally, these devices make it SO easy to zoom that it’s completely natural to do so and zooming too much makes things ugly again.

Enter SVG. The VentureBeat logo at 50 × 35 was 1.9k, but making it 100 × 70 for these high-density displays made it 5.9k! The SVG? 1.4k! And when you zoom in it still looks smooth and beautiful. Here’s the CSS we used to add the SVG logo:

#logo {
	background-attachment: scroll;
	background-image: url(../images/logo.svg);
	background-position: left 50%;
	background-repeat: no-repeat;
	-o-background-size:      100%;
	-moz-background-size:    100%;
	-webkit-background-size: 100%;
	background-size:         100%;
	font-size:10px;
	height: 3.5em;
	width: 5em;
}

The background-attachment, background-image, background-position, and background-repeat are up to you. The magic comes from background-size (and unfortunately it’s browser-specific counterparts). Forcing the background image to be the same size as the element it’s part of and setting the size of that element in ems means that the background image will scale as needed. You can also specify background-size in ems (width then height) if you don’t necessarily want it to take up the whole element. Just don’t use pixels or you lose the magic.

That seems so easy! What’s the big deal? Why not use these all over? Well, not all devices support them. Unfortunately it seems that older Androids (like my beloved Droid X) don’t support SVG because Google said it would have added 1M to the size of the browser. So now we need a fall back, but first we need to figure out how to tell if SVG is supported. We already had jQuery on the front-end of the site, so we used this snippet:

jQuery( function($) {
	var SVGsupport = false;
	try {
		var svg = document.createElementNS( "http://www.w3.org/2000/svg", 'svg' );
		SVGsupport = typeof svg.createSVGPoint == 'function';
	} catch(e){}
	if ( ! SVGsupport )
		$( 'body' ).addClass( 'nosvg' );
} );

If you don’t have jQuery already set up, don’t do it just for this. Just use the code that does the detection and add the class “nosvg” to the body element if svg is not supported. Now we have a nice way to tell when to use the fall back, so here it is:

.nosvg #logo {
	background:transparent url(../images/logo.png) no-repeat scroll top left !important;
	height: 35px;
	width: 50px;
}

So in the end it’s definitely more complex than just using multiple images, but it works everywhere and to me the quality is worth it.

2 thoughts on “SVG for Mobile in the Real World

  1. Thanks for a great post Aaron! I’ve had great luck creating glyph fonts for simple icons, but it’s pretty complex as well. I’m looking forward to giving this a try!

  2. This is perfect! I’ve searched for a simple explaination of SVG vs PNG and after weeks of searching, your post was dead on.

    Thanks!!

Leave a Reply

Your email address will not be published. Required fields are marked *