2013-08-19

There is a very clever technique by Alexey Ten on providing an image fallback for SVG going around the internet recently. It does just what you want in the classic no-SVG-support browsers IE 8- and Android 2.3. If we dig a little deeper we find a some pretty interesting stuff including a bit of unexpected behavior that is a bit of a bummer.

Alexey's technique looks like this:

The idea was based on Jake Archibald's revisiting of the fact that browsers render the <image> tag like <img>. It's just a weird alias from the days of yore that can be exploited.

What Displays

The technique is pretty close to perfect in terms of what supporting and non-supporting browsers display. IE 8, which doesn't support SVG, it displays the fallback PNG. Android 2.3, same story.

The part I got confused on was iOS 3 and 4. The native browser on those operating systems do support SVG, in the form of <img src="*.svg"> or as a CSS background-image. But with this technique, the PNG displays rather than the SVG. The trouble is that iOS 3 & 4 don't support "inline" SVG (e.g. using SVG with an <svg> tag right in the HTML) (support chart). SVG support isn't as simple as yes/no. It depends on how it is used.

The point: it's weird to see <img> work and <image> not work in these cases. And since those browsers do support SVG, it's a shame not to use it.

What Downloads

Of course we also care about what gets downloaded because that affects page performance. Again it's mostly good news. Modern browsers like Chrome only download the SVG. Android 2.3 only downloads the PNG.

But we run into an issue with Internet Explorer versions 9, 10, and 11 (a preview at this time). In IE 9, you can see both images turn up in the Network timeline.



The PNG ends up with a result of "Aborted" and listed as 0 B received, but still affects the download timing.

It is a similar story in IE 10, it just seems to abort quicker and move on to the SVG without much downtime.



Scott Jehl suggested using Charles Proxy to test what is being downloaded more accurately. Charles verifies that the PNG is being requested.



The size of the response body is indeed 0 B, so the abort happens fast enough that not much data is transferred. Although the request and response header combined is 782 B and it takes ~300 ms to happen. A Yoav Weiss points out, the problem may be worse if there are blocking scripts at the top of the page.

Also note there is some chance that using a proxy affects what is/isn't downloaded as Steve Souders points out in this Jason Grigsby article about Charles Proxy.

Research by Andy Davies suggests that the PNG request isn't aborted at all in IE 11 on Windows 7.

@stopsatgreen @jaffathecake @chriscoyier In my IE11 / Win7 response isn't aborted and shows up in dev tools and pcap pic.twitter.com/ypitwTYAAH

— Andy Davies (@andydavies) August 19, 2013

Findings

I did the display tests from this Pen, but the download tests I made sure to do with just one of the techniques present on the page and using Debug View so there was nothing else on the page but the raw technique.

See the Pen SVG Tests by Chris Coyier (@chriscoyier) on CodePen

So, Fallbacks

The Alexey Ten is still clever and if the iOS display issue and IE download issue is acceptable to you, it's still usable. Here's some more fallback techniques, which differ depending on how you use SVG.

If you're using SVG as a background-image...

Modernizr has an SVG test. So you could declare a fallback with the class names it injects onto the HTML element.

That shouldn't have any double-download issues.

If you're using SVG as <svg>...

That means you're probably already OK with the slightly-lower support for inline SVG. Meaning the <image> technique might be OK for you:

David Ensinger posted a technique using the <foreignObject> tag in <svg>. But the trouble with that is the fallback is loaded no matter what resulting in the double download all the time instead of just sometimes like the <image> technique.

You could do something like:

Then use the Modernizr SVG test again to get the support HTML class and then...

If you're using SVG as <object>...

You could use the object tag itself as the element to style after the Modernizr test.

If you're using SVG as <img>...

Scott Jehl prefers:

That requires HTML though, so if that's not possible or practical for you, you could swap sources with Modernizr. This uses the JS API of Modernizr, not the class names:

Where fallback is a string of a URL where the non-SVG image fallback is. You could keep it in a data-fallback, use a consistent URL pattern where it just replaces .svg with .png, or whatever other smart thing you can think of.

SVGeezy is a library just for this.

Or you could use a similar technique as with the inline SVG and object techniques where a hidden DIV is displayed with a fallback.

Alrighty Then

If this post didn't mean much to you because you aren't using SVG yet, you should because it's awesome. This post could help you get started.

If you have more data to share, we'd love to hear.

Good luck!

SVG Fallbacks is a post from CSS-Tricks

Show more