60

I'm writing a bit of javascript and need to choose between SVG or VML (or both, or something else, it's a weird world). Whilst I know that for now that only IE supports VML, I'd much rather detect functionality than platform.

SVG appears to have a few properties which you can go for: window.SVGAngle for example.

Is this the best way to check for SVG support?

Is there any equivalent for VML?

Unfortuntaly - in firefox I can quite happily do all the rendering in VML without error - just nothing happens on screen. It's quite hard to detect that situation from script.

Crescent Fresh
  • 115,249
  • 25
  • 154
  • 140
Jim T
  • 12,336
  • 5
  • 29
  • 43
  • 1
    interesting article on this argument: http://voormedia.com/blog/2012/10/displaying-and-detecting-support-for-svg-images – Stefano Apr 07 '14 at 07:39

8 Answers8

56

I'd suggest one tweak to crescentfresh's answer - use

document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")

rather than

document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Shape", "1.0")

to detect SVG. WebKit is currently very picky about reporting features, and returns false for feature#Shape despite having relatively solid SVG support. The feature#BasicStructure alternative is suggested in the comments to https://bugs.webkit.org/show_bug.cgi?id=17400 and gives me the answers I expected on Firefox/Opera/Safari/Chrome (true) and IE (false).

Note that the implementation.hasFeature approach will ignore support via plugins, so if you want to check for e.g. the Adobe SVG Viewer plugin for IE you'll need to do that separately. I'd imagine the same is true for the RENESIS plugin, but haven't checked.

Levi Lindsey
  • 1,049
  • 1
  • 10
  • 17
mrec
  • 760
  • 1
  • 8
  • 16
  • Good call. I almost walked on that mine. – Phil May 09 '12 at 13:46
  • @masterxilo: Chrome 35.0.1916.114 on Win7 returns true for #BasicStructure. It still returns false for #Shape though - are you sure you tried the right one? – mrec May 28 '14 at 20:12
  • https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature says this is removed, do you know if there is any alternative for his api? – mabeiyi Dec 09 '15 at 21:28
46

The SVG check didn't work for me in Chrome, so I looked at what the Modernizer library does in their check (https://github.com/Modernizr/Modernizr/blob/master/modernizr.js).

Based on their code, this is what worked for me:

function supportsSVG() {
    return !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', "svg").createSVGRect;
  }
Pamela Fox
  • 549
  • 5
  • 2
39

For VML detection, here's what google maps does (search for "function Xd"):

function supportsVml() {
    if (typeof supportsVml.supported == "undefined") {
        var a = document.body.appendChild(document.createElement('div'));
        a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
        var b = a.firstChild;
        b.style.behavior = "url(#default#VML)";
        supportsVml.supported = b ? typeof b.adj == "object": true;
        a.parentNode.removeChild(a);
    }
    return supportsVml.supported
}

I see what you mean about FF: it allows arbitrary elements to be created, including vml elements (<v:shape>). It looks like it's the test for the adjacency attribute that can determine if the created element is truly interpreted as a vml object.

For SVG detection, this works nicely:

function supportsSvg() {
    return document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Shape", "1.0")
}
Crescent Fresh
  • 115,249
  • 25
  • 154
  • 140
  • 1
    Ok, this is good. The VML detection is working fine, however the SVG detection fails in firefox. In fact, firefox denies all SVG abilities on http://www.howtocreate.co.uk/tutorials/jsexamples/hasFeature.html. – Jim T Mar 17 '09 at 21:13
  • 1
    As a compromise to firefox, I'm combining my old window.SVGAngle check with the much nice feature check, if either succeed, then it's supported. If you can fix up, improve on or remove the supportsSvg function, I can accept your answer. – Jim T Mar 17 '09 at 21:16
  • Hmm, latest firefox on both linux & windows fails that. However, interestingly, it succeeds for: "http://www.w3.org/TR/SVG11/feature#Shape" – Jim T Mar 17 '09 at 21:30
  • I found the Shape attribute here: "http://www.din.or.jp/~hagi3/JavaScript/JSTips/Mozilla/Samples/hasFeature.htm" – Jim T Mar 17 '09 at 21:33
  • Well that does seem a more specific feature check. – Crescent Fresh Mar 17 '09 at 21:48
  • I've updated the answer to use `feature#Shape` instead of `feature#SVG`. #SVG is too "catch all" that obviously FF corrected in v3. – Crescent Fresh Mar 17 '09 at 22:22
  • Shame really, I much prefer the idea of detecting #SVG. Oh well, reality strikes. – Jim T Mar 18 '09 at 09:00
  • I realize now though that testing for feature "#SVG" is like testing if a browser "supports html". It's so open-ended, it makes sense to test for a specific feature of SVG, like drawing shapes (which is so fundamental) to svg. – Crescent Fresh Mar 18 '09 at 12:51
  • Don't forget too that you are testing for svg as a global feature by specifying "http://www.w3.org/TR/SVG11/feature" before the # hash. – Crescent Fresh Mar 18 '09 at 14:59
  • @CrescentFresh Maybe you could update the answer with the suggestion made by Mike C ? – Potherca Jan 08 '11 at 15:57
  • 1
    FYI you have to define the v namespace prefix document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML'); – user472749 Apr 27 '12 at 21:12
  • 1
    This is a working SVG support check from wout's svg.js https://github.com/wout/svg.js/blob/master/src/svg.js#L67 – Stan Bondi May 09 '13 at 14:20
4

You might like to skip this and use a JS library which will allow you to do vector drawing cross-browser, if that's the intention. The library will then handle this, outputting to SVG if supported or fallback to canvas, VML, flash, silverlight, etc if not, depending on what's available.

Examples of libraries that will do this are, in no particular order:

Brad
  • 159,648
  • 54
  • 349
  • 530
Duncan Lock
  • 12,351
  • 5
  • 40
  • 47
  • 1
    The raphaeljs demos are incredible. +1 for turning me on to that. – Koobz Feb 15 '10 at 04:44
  • 2
    Raphael is indeed incredible, I love it and recommend it to everyone. But it was just too slow for one particular thing I wanted to do. I also didn't feel that the way that raphael detected svg was very nice (I can't remember what that was now), and wondered if there was a better, more official way to do it, hence the question. – Jim T Jun 13 '10 at 23:02
3
var svgSupport = (window.SVGSVGElement) ? true : false;

Works, if you assume that non-SVG browsers are IE5.5 or better and can support VML. Tested on IE6, Firefox 8, Chrome 14.0.

Raphael is very cool, but it does not support the concept of groups, which can be limiting depending on what you are doing. Dmitry will probably flame me for saying so, though.

eeerahul
  • 1,629
  • 4
  • 27
  • 38
3

You may want to check out http://www.modernizr.com/docs/#features-misc as it contains support for actual detection of SVG capability as opposed to user-agent sniffing which can be easily corrupted.

Norman H
  • 2,248
  • 24
  • 27
2

The SVG-check did not work in Chrome because it specifies version 1.0. This should work better:

document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Shape", "1.1")
Alex_S
  • 21
  • 2
1

On the other hand... When you want to know before you serve the page: Scrape this page: http://caniuse.com/#cats=SVG&statuses=rec&nodetails=1 For the incoming browser/user agent. Disclaimer: I've not yet implemented this. As I'm hoping caniuse.com will publish an api to work with.

MarkT

MarkT
  • 21
  • 1
  • Yes, I'd rather work with an API for this too. In my case I was using static files, so this wasn't an option, but a good idea though. – Jim T Jan 13 '12 at 13:46