How do you detect support for VML or SVG in a browser
Asked Answered
T

8

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.

Tracee answered 17/3, 2009 at 12:58 Comment(1)
interesting article on this argument: voormedia.com/blog/2012/10/…Customable
F
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")
}
Firstnighter answered 17/3, 2009 at 14:38 Comment(12)
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 howtocreate.co.uk/tutorials/jsexamples/hasFeature.html.Tracee
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.Tracee
Hmm, latest firefox on both linux & windows fails that. However, interestingly, it succeeds for: "w3.org/TR/SVG11/feature#Shape"Tracee
I found the Shape attribute here: "din.or.jp/~hagi3/JavaScript/JSTips/Mozilla/Samples/…"Tracee
Well that does seem a more specific feature check.Firstnighter
I've updated the answer to use feature#Shape instead of feature#SVG. #SVG is too "catch all" that obviously FF corrected in v3.Firstnighter
Shame really, I much prefer the idea of detecting #SVG. Oh well, reality strikes.Tracee
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.Firstnighter
Don't forget too that you are testing for svg as a global feature by specifying "w3.org/TR/SVG11/feature" before the # hash.Firstnighter
@CrescentFresh Maybe you could update the answer with the suggestion made by Mike C ?Phonology
FYI you have to define the v namespace prefix document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML');Camboose
This is a working SVG support check from wout's svg.js github.com/wout/svg.js/blob/master/src/svg.js#L67Eroticism
W
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.

Wershba answered 1/4, 2009 at 17:30 Comment(3)
Good call. I almost walked on that mine.Despinadespise
@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?Wershba
developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/… says this is removed, do you know if there is any alternative for his api?Polygynist
W
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;
  }
Wavawave answered 30/3, 2011 at 23:17 Comment(0)
F
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")
}
Firstnighter answered 17/3, 2009 at 14:38 Comment(12)
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 howtocreate.co.uk/tutorials/jsexamples/hasFeature.html.Tracee
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.Tracee
Hmm, latest firefox on both linux & windows fails that. However, interestingly, it succeeds for: "w3.org/TR/SVG11/feature#Shape"Tracee
I found the Shape attribute here: "din.or.jp/~hagi3/JavaScript/JSTips/Mozilla/Samples/…"Tracee
Well that does seem a more specific feature check.Firstnighter
I've updated the answer to use feature#Shape instead of feature#SVG. #SVG is too "catch all" that obviously FF corrected in v3.Firstnighter
Shame really, I much prefer the idea of detecting #SVG. Oh well, reality strikes.Tracee
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.Firstnighter
Don't forget too that you are testing for svg as a global feature by specifying "w3.org/TR/SVG11/feature" before the # hash.Firstnighter
@CrescentFresh Maybe you could update the answer with the suggestion made by Mike C ?Phonology
FYI you have to define the v namespace prefix document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML');Camboose
This is a working SVG support check from wout's svg.js github.com/wout/svg.js/blob/master/src/svg.js#L67Eroticism
T
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:

Therefrom answered 27/1, 2010 at 1:55 Comment(2)
The raphaeljs demos are incredible. +1 for turning me on to that.Sandbank
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.Tracee
P
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.

Plagiarism answered 18/11, 2011 at 6:6 Comment(2)
Might i suggest var svgSupport = !!(window.SVGSVGElement);Doublejointed
You may! I don't really know jack about JavaScript.Plagiarism
G
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.

Garble answered 26/1, 2012 at 20:45 Comment(1)
Yes, modernizr is a good response to this problem these days.Tracee
N
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")
Nurserymaid answered 13/6, 2013 at 16:26 Comment(0)
S
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

Schwarzwald answered 9/1, 2012 at 6:36 Comment(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.Tracee

© 2022 - 2024 — McMap. All rights reserved.