SVG vs PNG Uber Architects

Add PNG Fallbacks for SVG Files without JavaScript

Last week I put the finishing touches on a new website for Uber Architects.

I wanted to use SVG files for the images, because vector graphics provide crisp lines at any size. This makes them a perfect candidate for high-density displays.

When we zoom in on the Uber Architects logo, you can see the difference in the crisp SVG on the left, and the pixelated PNG on the right.

SVG files vs PNG files Comparison

The Problem with SVG Files

Unfortunately, vector graphics are only supported by modern web browsers, and won’t render in IE 8 or earlier.

I spent a couple hours flipping through articles and trying to hack together CSS solutions myself with little luck. I thought I could make it work by stacking the imageI found a few ways to get around this using JavaScript, but I felt there had to be another option.

The Invisible Linear Gradient

Nested away in a comment thread I found a promising CSS solution by Pau Giner. Rendering a background image, and then using a transparent linear gradient to overlay the SVG.

The idea is simple: browsers capable of using CSS gradients are modern enough to support SVG rendering. So, if we use a background image that is composed of two layers, one being the SVG and the other being a gradient, only those browsers capable of understanding the gradient syntax will try to display the SVG.

Here is the CSS for the logo on our website.

.uxa-logo {
/*Renders a png background image*/
background: transparent url(../img/uber-architects-logo.png) center center no-repeat;

/*Modern browser supporting linear gradients will render an svg over the png*/
background-image: -webkit-linear-gradient(transparent, transparent), url(../img/uber-architects-logo.svg);
background-image: -moz-linear-gradient(transparent, transparent), url(../img/uber-architects-logo.svg);
background-image: linear-gradient(transparent, transparent), url(../img/uber-architects-logo.svg);

background-size: 100% 100%;
height: 50px;
width: 50px;

This has worked perfectly in every older browser I’ve tested. The SVG is served in newer browsers, while older ones are served the PNG.



Are you a designer, developer or entrepreneur? We’ll keep you posted with interviews, articles and great content. Just subscribe.



  • Matt

    Great, solution – I’ve tested it in browser stack for android 2.2 and it works as expected – the png fall back renders rather than the svg. Is there a need to declare other vendor prefixes (-o, -m)?

  • Erwin

    Hi. Seems a bit hacky. Since linear-gradient has about the same support matrix as multiple background images in browsers, why not simply use “background-image: none, url(image.svg);”? Then eveything that does not support multiple background images will fall back to the png.

  • Tim

    I just checked on my G2X running Android 2.2 and it looks great!

    • Sam Solomon

      Glad to hear it Tim! I still use this solution when building sites. It is a little hacky, but it gets the job done.

  • David Millar

    I’m not sure if transparent gradients require much (if any) calculation time on the browser’s part, but I’ve seen others use a similar technique using rgba(0,0,0,0) along with the SVG image, assuming only browsers that understand RGBA will use the SVG. Still doesn’t fix the Android issue, but may be a less resource0heavy way of doing this trick anyway.

  • Igor Aleksic

    For IE6-8 or 9 i think we could implement CSS3PIE for rendering gradients and etc if that solves a problem, but for android that are older than 3 and cant render svg’s we can use canvas. So just using javascript to convert SVG to Canvas will be fine for the older ones.

  • Ben Frain

    Hi, IE 9 supports SVG but not gradients so that may be something to be aware of. I wouldn’t lose any sleep over it but may be worth pointing out.

    There’s also support for gradients in Android 2.0 – 2.3 (but no SVG support) so that could be an issue too?

    • Sam Solomon

      This didn’t have any issues in IE9 when I tested it.

      I have seen others say variants of this method have problems in Android 2.x, but haven’t been able to test it. If anyone reading this post has an older Android phone please let us know if it works.

      Thanks for the comment Ben!