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.

12 thoughts on SVG and VML in One Chameleon File

  1. For the content type, surely you could juse some PHP or other server-side script to detect the HTTP_ACCEPT header and then server it with the proper MIME type.

    Interesting ‘thought experiment’, but I wonder how useful this can be. Certainly I can see how this might work for some small subset of static vector images – but probably not for complex images with gradients, stroke styles, etc – and definitely not for dynamic/interactive images.

    And when IE9 supports SVG you’ll have another problem – both images will be displayed (of course you can use conditional comments for IE8-).

    But the worst is that you have to maintain the image data in two formats, they could quickly get out of sync. Why not use dojo.gfx or RaphaelJS to abstract away the differences completely?

  2. Great work trying to beat everything into one file but I think you still run the risk that you mentioned earlier, namely “if someone changes one, they probably won’t bother changing the other one” In this case the editor is likely to know about the data that’s not SVG in the file but they won’t likely be able to edit it. I expect that for editing they’d have to split into two files then re-merge since one tool won’t edit both formats as far as I know.

    Maybe it could be a workable format with a script that does the split & re-merging. The chameleon file could also see more use for sites that generate vector graphics server-side and don’t want to serve different content to different UAs.

  3. Jeff, useful feedback.

    You probably could set things up on the server, but a key goal here is simplicity – e.g. so I could just mail around a file. A lot of this is related to our work on TiddlyWiki, which is just a single file and where we’d like to embed drawings.

    IE9 – interesting thought! It will probably be possible to use if a conditional IE version hack, but I’ll be happy enough if SVG is supported and cross that bridge when that day happens.

    It probably doesn’t work for gradients etc, you’re right – hopefully this thought experiment will lead others to think of further refinements that might work for things like that.

    It’s true – using a higher level abstraction might end up being the best option for this, much as it would be nice to avoid relying on JS processing. At least it’s worth exploring how far we can go without it.

  4. RewriteEngine On RewriteCond %{HTTPUSERAGENT} ^(.MSIE.)|(Lynx.)$ RewriteCond %{REQUEST_URI} ^.+.xhtml$ RewriteRule ^.$ – [T=text/html] [L]

    Or better yet check for HTTP Accept header for application/xhtml+xml.

  5. Hi,

    Interesting topic.

    I did several tests with a chameleon SVG / VML chameleon page.

    In this folders are some test files : http://www.altipoint.ch/svg_vml/

    All have the same content, excepted that the DOCTYPE defintion was removed for some of them. Before some files, I put an underscore so that it is possible to see the content of the folder.

    The main problem relates to expected file extensions: xhtml, svg, and xml for Opera. htm, html, vml for MSIE.

    Something more neutral is using no extension and specify Content-type with a meta tag. But this works only with MSIE (not Firefox nor Opera).

    The presence of a DOCTYPE is also a problem with MSIE 8 and prevents the VML to display.

    The “.svg” and “xhtml” extensions provocate a “Save as” popup to show.

    The file extension in which I have the most hope for a hybrid page is “.xml”. But the XML nodes display in MSIE.

    I agree that url rewriting is a good solution.

    One challenge that remains is displaying side by side VML and SVG content in MSIE* so that comparing the SVG and VML outputs can be done in a glance. Can this be achieved ?

    (*using Adobe’s plugin or other for the SVG part).

    Note that with the “.svg” extension, Firefox and Opera display all correclty. For a local file, MSIE displays the page source code, but a click on the “Refresh” button then make the page interpreted as xhtml/vml. Interesting for local testing. However this cannot be combined with Adobe’s SVG plugin.

  6. Pingback: Microsoft and SVG. In the same room? | otrops

  7. Pingback: Links for 2009-05-01 [del.icio.us] :: Sixty Sigma Leadership Development

Leave a Reply