Vector graphic formats such as SVG are great for high-density displays since their lines are clean at any zoom level. However, not all browser support SVG and there is not an obvious way to provide a fallback (using png, jpg or gif instead) for those browsers not supporting vector graphics.
These days I was experimenting with a technique for SVG fallback support that does not require Javascript code, server-side processing or browser-specific CSS hacks.
The invisible gradient technique
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.
The following code shows the basic CSS rules:
background: transparent url(fallback-image.png) center center no-repeat;
background-image: linear-gradient(transparent, transparent), url(vector-image.svg);
The first line defines the fallback using a PNG image as background. The second redefines the image using two features that only browsers which support SVG provide: CSS gradients and multi-layer backgrounds (define more than one image per background separated with commas). This guarantees that only SVG-capable browsers will try to render vector-image.svg in the example.
The technique is restrictive on purpose to make sure that SVG is only provided to SVG-capable browsers. As a consequence, we can be sure that all users will see the image. The price to pay is that some browser versions (such as IE9 or Firefox 3.5) that are also capable of rendering SVG but do not support gradients will display the fallback version.
A demo is available where you can inspect the code and zoom the image to check which version is loaded in your browser.
Adjusting browser support
Since the linear-gradient property is still supported with vendor-specific prefixes on some modern browsers such as Safari and Android 4.x browser, you can add a webkit-specific rule if you don’t mind the code to be a bit more verbose:
background: transparent url(fallback-image.png) center center no-repeat;
background-image: -webkit-linear-gradient(transparent, transparent), url(vector-image.svg);
background-image: linear-gradient(transparent, transparent), url(vector-image.svg);
Note that we did not include the old syntax for gradients used by Webkit. By doing this, Android 2.x browser (which lacks SVG support) will load the fallback image. That was not possible with techniques based on multiple backgrounds.
Feel free to use the “invisible gradient” technique to make your websites more friendly to high-density devices without breaking the experience for those with older browsers.