SVG and VML in One Chameleon File

Why a Chameleon File?

While most browsers support SVG, IE’s unique brand of interopability does not extend that far; even the latest and greatest, incarnation v. 8 of IE, has no sign of SVG. And so, we citizens of the innernets are left with two vector graphics formats: VML for IE, SVG for standards-compliant browsers, which I will simply refer to as “Firefox” for concreteness.

There are tools like Project Draw capable of rendering both SVG and VML, and there are convertors like Vector Convertor as well. You can easily end up in a situation where you have two separate files for the same image. In one’s endless quest for a simple life of zen-like existence, this is troublesome. You will have to mail the two files around or host the two files somewhere. And if someone changes one, they probably won’t bother changing the other one.

One solution would be to convert to a raster/bitmap file, i.e. GIF or PNG, which will then render fine in IE and standards-compliant browsers as well as many other places too. However, this isn’t always the best option: (a) if you want to support further editing, you will need the original vector data; (b) it won’t scale as nicely; (c) in some cases, the bitmap size is bigger by orders of magnitude.

So a colleague asked me how one could share this type of data and I got thinking about a recent experiment. I need to blog it separately, but the premise is that a single file can be different things to different people. In this case, we did some work yesterday I’ll describe here – seeing how a single file can look like VML to something that works with VML (IE) and look like SVG to something that works with SVG (Firefox et al). In the general case, I call this pattern “Chameleon File” and the particular kind of chameleon described here I call a “Vector Graphics Chameleon File”.

Demo

The demo link is below – it shows an ellipse in any browser, using either VML or SVG, whichever is supported:

http://project.mahemoff.com/vector/ellipse.xhtml

IE users are better off using http://project.mahemoff.com/vector/ellipse.html as it won’t launch automatically in IE as Windows doesn’t recognise the xhtml extension, though it will still launch once you tell windows to open it with IE. The content is the same, the URL is different. I’ll explain more below in “Limitations”.

(The example is taken from Wikipedia’s VML page.)

How?

How does it work? Let’s look at the source:

  1. <html xmlns:v="VML">
  2. <!--[if IE]>
  3. <style>v:*{behavior:url(#default#VML);position:absolute}</style>
  4. <![endif]-->
  5. <body>
  6.  <v:oval style="left:0;top:0;width:100;height:50" fillcolor="blue" stroked="f"/>
  7.   <svg xmlns="http://www.w3.org/2000/svg" width="100" height="50">
  8.     <ellipse cx="50" cy="25" rx="50" ry="25" fill="blue" stroke="none" />
  9.   </svg>
  10. </body>
  11. </html>

From Firefox’s perspective, the file is valid XHTML thanks to the .xhtml suffix, meaning that the svg tag is fair game. We use the old “if IE” comment trick to get Firefox to ignore the style rule; otherwise it will still work, but it will render the style tag’s content (this is XML, not HTML, which would have it un-rendered). It ignores the body and VML v:oval tag, and faithfully renders the SVG. In short, it does what the pure SVG does:

  1. <html xmlns:v="VML">
  2.  <style>v:*{behavior:url(#default#VML);position:absolute}</style>
  3. <body>
  4.  <v:oval style="left:0;top:0;width:100;height:50" fillcolor="blue" stroked="f"/>
  5. </body>
  6. </html>

From IE’s perspective, this is just a normal VML file with an svg tag snuck in, which thankfully for our purposes, it ignores. So IE sees the file as just regular old VML:

  1. <?xml version="1.0"?>
  2. <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  3.  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
  4. <svg xmlns="http://www.w3.org/2000/svg" width="100" height="50">
  5.   <ellipse cx="50" cy="25" rx="50" ry="25" fill="blue" stroke="none" />
  6. </svg>

Limitations

Limitations, I have a couple of those.

File Extensions

The extension thing is really annoying (see also here). To get SVG working in Firefox, you need Firefox to see the file as XHTML. But to get VML working in IE, IE must see it as HTML. How do you make the browser “see the file” as something? You either set the MIME type in the HTTP header, or you set the file’s extension. In this case, we’re more interested in the file extension because we want to be able to just mail the file around – in which case there is no MIME type because there’s no HTTP header because there’s no HTTP because they’re viewing it off a file:/// URL – or we want to quickly stick it on a server and not bother faffing with .htaccess-fu and MIME types.

Now that being the case, what file extensions do we need? As far as I can tell, IE must have .html or .htm for the vanilla Windows operating system to open it.

As for Firefox, Firefox needs .svg or .xml or .xhtml as far as I can tell.

The problem here is there is no overlap – IE needs .html and .htm, Firefox needs .svg, .xml, .xhtml.

skitched-20090501-101849.jpg

I spent a while trying to coerce Firefox to see a .html file as XHTML using doctype and the like, but I can’t do it – any help here would be appreciated.

The consequence is that you have several possibilities: (a) call it .xhtml/.svg/.xml – it will run on Firefox and IE users will have to “open”, “choose application”, and set IE (and they can save that setting); (b) call it .html (or .htm but that’s just silly) and tell Firefox users to rename the file; (c) distribute two copies of the same file – defeats the purpose of simplicity to some extent, but since it’s still the same file, it’s not such a big deal; you can keep working with the one file until you’re ready to distribute it. Of (a) and (b), I prefer (a) because asking someone to “open with application X” is less onerous than asking someone to rename a file, which sounds a bit odd. On the other hand, in many enterprise situations, you have to optimise around IE users, in which case (b) may well be preferable. You could probably also ship the file with a little instruction to rename the file, targeted at non-IE users using CSS/Javascript hacks, which they will see on opening the file in its HTML guise.

SVG and VML Feature Sets

I haven’t experimented much with these, but I did find a larger SVG file that didn’t work properly. I’m hoping Project Draw will introduce an easy way to render both SVG and VML for the same file, which would let me script creation of SVG-VML chameleon files for experimentation; or I might just play aronud with a converter. Any data on this would be welcome.

The Chameleon File Pattern

… is rather interesting and useful. Some interesting analogies came up in discussion – one of them was the “old woman, young woman” optical illusion. I discovered it’s called a “Boring figure” after the experimental psychologist Edwin Boring. I thought “chameleon file” sounded more appropriate than “Boring file”!

Another analogy from Paul was the Rosetta Stone – same content in a different format. I think this is a good analogy, but at the same time, I guess the pattern could be used to contain different content too. That’s more the case with the JOSH Javascript-HTML Chameleon I’ll discuss later on.

It also reminds me of Zelig, an old Woody Allen flick about a “human chameleon” who tries to be all things to all people, although I think chameleon files have more of their own unique identity.

Chamelon File is a hammer, let’s go find some nails.

Thanks to my colleagues for ideas and inspiration.