Scalable Vector Graphics verus Portable Network Graphics

I started using Sketch to develop web designs about a year ago and I’ve been using Scalable Vector Graphics (SVG) for icons, where I would have previously used PNGs (Portable Network Graphics), ever since. On the whole I’ve been really happy using SVGs until this week when I encountered a situation where using PNGs turned out to be better.

The Benefits of SVG

The benefits of SVG are plenty and the clue to the main benefit is in the name, scalability. As SVGs are vector based they can be viewed at any size without a loss of quality, unlike bitmap image formats like PNGs or GIFs, which means the image sizes are relatively small whatever size the image is rendered.

This is also really useful for so-called retina displays. SVGs do not suffer the fuzziness of PNGs and GIFs that aren’t optimised for high-resolution screens. Sure, you can serve an @2x image for retina, but this requires the creation of 2 images as well as extra CSS coding although if you’re using a CSS pre-processor like Sass or Less writing a mixin to handle the fallback is not particularly difficult.

SVG is also an open source standard developed by the W3C and, and although they aren’t supported in IE8 it’s easy enough to provide a fallback to serve a PNG image in place of the SVG. Otherwise broswer support for SVG is good so there’s really good support amongst all modern browsers so using them is really a no brainer.

When Not To Use SVG

Until this week there’s not been any situations where using an SVG hasn’t seemed like the obvious solution for simple graphics. On this website I use SVGs for the logo and social media icons as well as a few other icons.

They serve their purpose well; displaying crisply on any resolution screen whilst file sizes are comparable to PNGs, if not smaller than retina PNGs.

This week I embarked on creating a list of clients that required client logos to be displayed in an HTML list. This seemed like a fairly straightforward task; create the logo graphics in Sketch, export them, create an un-ordered list of clients in HTML and then set background images in the CSS. Simple.

However after exporting the SVG images of the client logos I noticed that one of the logos was MUCH larger in file size than all the others. Whilst most of the retina PNG images were perhaps double the size of the SVG, the retina PNG logo for The OECD was 41kb (the standard version 16kb) whereas the SVG version was a staggering 733kb. That’s nearly 18 times the file size!

I opened up the SVG in a text editor and saw that the file contained 733015 characters. By comparison the SVG file for the Tesco logo was 6568 characters.

The logo for The OECD is reasonably complex due the inclusion of a world map and this was clearly the reason for the file size coming in so large.

PNGs to the Rescue

After some thought I decided to simply use PNGs. The logos are fairly small both physically and in file size and the single OECD SVG logo was larger than all of the 12 retina PNG client logos I was using combined.

Whilst I’m on the subject here’s the mixin I used for creating the PNG logos with retina versions.

// Mixin for handling retina images
@mixin background-image-retina($file, $type, $width, $height) {
  background-image: url($file + '.' + $type);
  @media only screen and (-webkit-min-device-pixel-ratio: 2),
    only screen and (-moz-min-device-pixel-ratio: 2),
    only screen and (-o-min-device-pixel-ratio: 2/1),
    only screen and (min-device-pixel-ratio: 2),
    only screen and (min-resolution: 192dpi),
    only screen and (min-resolution: 2dppx){
    & {
      background-image: url($file + '@2x.' + $type);
      -webkit-background-size: $width $height;
      -moz-background-size: $width $height;
      -o-background-size: $width $height;
      background-size: $width $height;
    }
  }
}
// List of clients
$clients: oecd tesco kyle-books yale foyles berlitz magdalen-arms whitney-murray waterstones daunt-books oxfam aa;
@each $client in $clients {
  .client-#{$client} {
    @include background-image-retina(img/#{$client}-logo-white, png, 80px, 80px);
    /* Image replacement code */
  }
}