7

I'm working on drawing shapes in my ASP.NET web app. In IE9 and other browsers, I'm doing it with SVG, and it's working great. In IE8 and below, I'm using VML. I'm finding that IE8 does not display the VML at all when it's in IE8 Standards mode (not using compatibility view).

My doctype is set to <!DOCTYPE html>. If I take the doctype away entirely, IE8 goes to quirks mode and works fine, but IE9 then goes to its quirks mode (instead of IE9 Standards) and doesn't display the SVG.

This is happening on a test page, so there's nothing there besides the form containing a div containing either the <svg> element and its children or the VML elements.

What is going on here? It seems like I shouldn't have to change the doctype for different browsers, and the reputation graph on Stack Exchange's user page appears to work the same way (VML for IE8 and below, SVG for everyone else, HTML5 doctype)...

miracules
  • 686
  • 7
  • 25
Tom Hamming
  • 10,577
  • 11
  • 71
  • 145
  • Have you thought about using condition statements on the doctype? `` I know it's not what your asking, but it might be an alternate solution. – Eruant Jul 10 '12 at 07:58

3 Answers3

5

There are a couple of more things you need to check:

Selector for the behaviour rules needs to be modified.

  • When setting dimensions or position of an element, the unit does not default to px. It must be explicitly specified to work.
  • You cannot create a VML element outside of the DOM:

.

var vmlFrag = document.createDocumentFragment();
vmlFrag.insertAdjacentHTML('beforeEnd',
'<v:rect id="aRect" fillcolor="red"         
style="top:15px;left:20px;width:50px;height:30px;position:absolute;"></v:rect>'
);
document.body.appendChild(vmlFrag);
  • The rect element won't be displayed! You cannot modify its CSS either as you will probably just crash the browser. However, there is a fix for it. Copy the outerHTML of the element into itself:

.

var aRect = document.getElementById('aRect');
aRect.outerHTML = aRect.outerHTML;
Michel de Ruiter
  • 7,131
  • 5
  • 49
  • 74
miracules
  • 686
  • 7
  • 25
3

To declare the VML namespace in IE8 Standards Mode, you'll need to include a third '#default#VML' argument:

document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML');

There are other changes to VML in IE8 that you may need to be aware of.

Jeffery To
  • 11,836
  • 1
  • 27
  • 42
  • I am actually using his suggestion at the bottom about forcing IE7 standards mode to make everything work. If it's IE8, then `Response.AppendHeader("X-UA-Compatible", "IE=EmulateIE7");` – Tom Hamming Jul 09 '12 at 15:47
1

HighCharts source code gave a solution. Besides adding the namespace at runtime, you also have to add a specific CSS behavior :

<!--[if lte IE 8 ]>
<script type="text/javascript">
    document.namespaces.add('vml', 'urn:schemas-microsoft-com:vml');
    document.createStyleSheet().cssText =
        'vml\\:fill, vml\\:path, vml\\:shape, vml\\:stroke' +
        '{ behavior:url(#default#VML); display: inline-block; } ';
</script>
<![endif]-->

After that, the js created elements will be visible on the page. Watch the demo.

nniico
  • 239
  • 2
  • 6