I'm currently doing some redesign of a website, basically just upgrading it to a more up-to-date look and trying to make it as resolution independent as possible, and in the name of resolution independence I figured I'd try to use SVG images in the design where the browser supports SVG images in <img>
tags. The reason I want to stick to just using SVG in <img>
tags rather than using some more ambitious solution is that AFAIK Chrome, Opera and Safari all support it and FF4 seems like it may finally get it as well combined with the fact that the entire site is built on a custom CMS which would have to be partially rewritten to start changing the output HTML (currently it supports custom design images, custom CSS and custom JS includes for each theme).
Now, I've looked around the net a bit myself trying to figure out the best way of doing this and for some reason pretty much every suggested solution I've found has worked poorly (one detect FF3.x as supporting SVG in <img>
tags so they didn't display properly there, another one never tried at all, several were overly complex "replace all images with SVG if there is support for it" functions which won't work too well either.
What I'm looking for is really a small snippet that can be called like this (btw, I'm using JQuery with this new theme for the website):
if(SVGSupported()) {
$('#header img#logo').attr('src','themes/newTheme/logo.svg');
/* More specified image replacements for CSS and HTML here */
}
Does anyone actually have a working solution for this that doesn't give inaccurate output? If so I'd be very grateful.
This appears to be the ultimate answer: Javascript: How can I delay returning a value for img.complete. Unless someone comes up with something yielding the correct results immediately.
For old browsers you could use the <object>
or <iframe>
tag, but that is not a nice solution. Firefox and IE9 (don't know about other browsers) have implemented inline svg now, which can easily be detected:
// From the Modernizr source
var inlineSVG = (function() {
var div = document.createElement('div');
div.innerHTML = '<svg/>';
return (div.firstChild && div.firstChild.namespaceURI) == 'http://www.w3.org/2000/svg';
})();
if( inlineSVG ){
alert( 'inline SVG supported');
}
So, you could replace all images by svg tags then. And I hope, but I have to google on that, that every browser that supports inline svg will support svg as image source.
A good discussion/comparison of methods is here:
http://www.voormedia.nl/blog/2012/10/displaying-and-detecting-support-for-svg-images
Based on that page, I wound up using this:
svgsupport = document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1")
I've been meaning to write a blog post about this, but here's a snippet that should work:
function SVGSupported() {
var testImg = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNzUiIGhlaWdodD0iMjc1Ij48L3N2Zz4%3D';
var img = document.createElement('img')
img.setAttribute('src',testImg);
return img.complete;
}
Based on a script by Alexis "Fyrd" Deveria, posted on his Opera blog.
I'm using something similar on my blog, which you can see in action here: http://blog.echo-flow.com/2010/10/16/masters-thesis-update-1/
It will use <img>
if supported; if not, and we're not on IE, it will use the a regular object tag; otherwise, it will use an object tag specially created for svg-web. fakesmil is used for the gradient animation. It seems to work everywhere I've tested it. The script that does the work for this example can be found here: http://blog.echo-flow.com/media/js/svgreplace.js
Use <object>
-Tags for displaying SVG.
See http://caniuse.com/svg-img and http://www.w3schools.com/svg/svg_inhtml.asp
Firefox 3.x can also display SVG images, just no embedded SVGs. I’m not sure about those on the other browsers neither. FF4 will also allow embedded SVGs.
With the <object>
-Tag you can also include alternative PNG-displaying of images, in case the browser does not support displaying SVG.