With the release of IE9 and Firefox 4 all major browsers are going to support using SVG in the img
element or as a CSS background image, which is great news as SVG images are good for high definition, scalable websites. I’ve written a couple of posts recently about using SVG with the background-image
property, and how to cope with browsers that don’t support it. The method I came up with works, but is far from elegant; for one thing, it doesn’t allow for transparency.
Another approach we can take to the problem is to use JavaScript to detect SVG support. Alexis Deveria wrote a script which detects if your browser supports SVG and, if not, replace the images with PNG. It’s a good script, but I wondered if there was an alternative.
I’ve come up with a script based on Alexis’s, but which simply adds a class to the body of the document, allowing you to specify alternative images if SVG support isn’t implemented on a visitor’s browser. Update: Changed the script to use onload
instead of addEventListener
to ensure compatibility with IE. Still looking into Opera issue.
Here’s the script:
function setCSS() { var docBody = document.getElementsByTagName('body'); docBody[0].className = 'svg'; } function SVGDetect() { var testImg = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNzUiIGhlaWdodD0iMjc1Ij48L3N2Zz4%3D'; var img = document.createElement('img'); img.setAttribute('src', testImg); img.onload = setCSS; } window.onload = SVGDetect;
This creates an img
element with an SVG data URI and tests to see if the browser loads it; if it does, it adds a class of svg to the body. To finish the method you just need to add alternatives in your stylesheet:
div { background-image: url('image.png'); } .svg div { background-image: url('image.svg'); }
Here’s a demo: Using SVG in CSS with JavaScript detection. View it in Safari, Chrome, Opera, IE9 beta or Firefox 4 beta to see the SVGs, and Firefox 3.6 or IE8 to see the PNGs. Try zooming in to the page to see the advantage of using SVG.
There are a couple of drawbacks with this method that need to be ironed out: first is that in theory it doesn’t work in browsers which allow SVG in the img
element but not in background-image
– in practice, however, there are no browsers where this is an issue; second is that it loads the PNG images first, and there’s a brief delay before the SVG images replace them – the script definitely needs tweaking to stop this, so consider it Version 0.1.
This technique is for the CSS background-image
only; if you want to replace img
elements I advise you to use Alexis’ script instead. As always, if you see a way in which my code could be optimised, don’t hesitate to let me know.
Update 20/05/12: The script I came up with in this post was a first attempt which I thought at the time was probably easily improved upon. See the comments of this post for different approaches which may be better.
Actually the test didn’t work for me in opera 10.62.
Spadar Shut [September 22nd, 2010, 21:54]
Wouldn’t an SVG browser load both images anyway, and then just use the SVG image even though both were downloaded & cached?
Devon Young [September 23rd, 2010, 09:25]
@Spadar – Thanks, I’ll look into that.
@Devon – That’s certainly the way it works at the moment, both PNG & SVG images are loaded; I’m not sure if that would be the case if I could get the script to load when the DOM is ready. I’ll look into it as I develop the script.
Peter [September 23rd, 2010, 12:28]
Actually, with the current firefox it is an issue: FF allows SVG in the img element but not as background-image. It probably will work in the next release (version 4.0) though, you can find a bug page here: (down in the comments) https://bugzilla.mozilla.org/show_bug.cgi?id=276431
xynn [December 9th, 2010, 17:39]
On the script above, you’re using…
img.onload = SVGDetect;
I believe you want…
window.onload = SVGDetect;
Like you do on your demo page.
Steve Schrab [September 20th, 2011, 16:26]
Wouldn’t you want to use PNG if SVG wasn’t supported?
So why not do something like this:
Ilya Shindyapin [May 19th, 2012, 18:39]
Thanks. Worked for me to detect Firefox 3.5 which doesn’t support svg background images in css.
matt [July 1st, 2012, 20:39]