Thoughts on SVG Graphics on the Web

So we all want HiDPI graphics on the web now, Apple started it all with Retina screens, and now most high-end Android and Windows devices have a 300+ PPI as well. With this, comes of course the problem of HiDPI graphics. Nobody wants 72 DPI graphics on their 300+ PPI screen.

And to make it interesting, I think most of you have to worry about IE 7 & 8 support, at least I do. It’s what makes our jobs interesting, right?

Translating this situation to the web, there are several ways to go. One of the easy ways is to create images that are twice as big, which generates 4 times the size. If you’ve got a photo, you might be forced into this solution. But we are talking about icons. For those kind of graphics, you could work with a library like Raphaël. Say your icon is suitable for it, this will get it on screen in all required browsers in no time. But, they do have performance drawback. Suddenly your visitors have to download an extra javascript library. And depending on whether you put it into head or body, either your page will load slower, or your page will become visible without the icons, which will appear later. I don’t want all that.

Continuing on how I do most of my CSS3 fallbacks, we can do a similar thing here. First, we write CSS3 code, then we target IE with a class coming from a conditional comment. Say we have a crimson arrow-ish icon. And since it’s our lucky day today, the icon is so simple, that we can reproduce it with only CSS. It might look like this.

But the designer didn’t sleep well last night, and this morning during our daily stand-up he announced the icon needed more pop. And thus we must iterate. This time however, the designed icon is not so simple, and we can’t get away with CSS-only trickery. We’re going to need a vector-based solution.

Applying my usual CSS3 fallback technique to an SVG file as a CSS background, should be easy. It loads the fallback .png in IE 7 & 8, and since it’s vector it can be enlarged without loss of quality. It also has advantages over using @font-face for vectors; the icon can use as many colors as you want, and can be in any ratio, not just the square-ish a font requires.

The 72 DPI .png image is enough for IE 7 & 8, since they’re not browsers typically run on HiDPI screens. Android 2.3 (which has about half of Android’s market share at the time of writing) might be a problem though, depending on your visitors. But the rest of the world can see your vectors nicely. See caniuse.com for detailed svg in css browser support.

And I’ll admit it right away; when your project has any kind of feature detection system (like Modernizr), I’d go with a .svg class on my element to place the .png, instead of an .ie class. But, if you’re only using svg, I’d prefer to have my conditional .ie classes, since I need them all the time anyway. If you have neither conditional .ie classes, or feature detection, a css-fallback technique like this one is a nice solution as well.

Additionally, I’d like to state, that the SVG syntax is not that hard to master, and if you’ve got an icon that’s not too complex, you can always write the SVG by hand, it’s just drawing with XML. It’ll create a much more optimized file than what you’d copy from your designer.

I find that, personally, I’m better writing code than I’m using Illustrator or Inkscape to create an .svg file. My designer of course isn’t, and he’ll gladly use those tools. The .svg exports from Illustrator aren’t that nice, for one it doesn’t understand relative vs absolute paths. You’ll want relative ones when you’re going to manipulate or animate elements. Inkscape has a setting for that, where you can choose between relative/absolute paths, which’ll save you a lot of headaches.

Which brings me to my last tip: optimizing svg files. Since Inkscape is build around the SVG standard, its Save as “Optimized SVG file” is pretty neat. I advise using it on all your SVGs, do check the results manually though, and you’ll learn SVG syntax in the process.