SVG to VML converter
Converting a watch was the SVG to VML test we were building up to
Lange watch
While I was doing some printing of an SVG watch Graeme had drawn, we thought it would be fun to see it render in Outlook. This lead to us working on an SVG to VML converter. Below is some of the process, and a look at VML layout and support. Mostly cropped screenshots of VML tests from my Outlook 2010 email client. VML was deprecated ~ 2011, and looks the same in all versions up to 2019. Click on images for full-size, or email yourself a test below.
Resources
- SVG to VML converter
- Selection of our VML email tests
- VML R&D Google deck
- VML / HTML to MHT converter
What is VML
VML is a 2D vector format supported in desktop Outlook, which uses Microsoft’ Word renderer. Although deprecated, it’s still all there, in the background. Email designers use VML to fill support gaps, most often with background images thanks to Stig Morten. Given the lack of VML authoring tools, if you want more than a button you’d have to hand code it, which Mark Robbins wrote about. So we decided to write an SVG to VML converter to display vectors in Outlook, and explore VML’s capabilities. SVG evolved out of a few 2D vector graphic formats that were around ( ~ 1998 ), one of which was VML ( Vector Markup Language ). So SVG is partly derived from VML, but not identical. There’s not a VML equivalent to everything SVG, but there’s enough overlap for our purposes. We're trying to make use of the, ‘whole lot of commonality’ between the specs.
SVG to VML converter
The core task is to convert all the basic SVG elements to VML
We need to convert all the basic SVG elements into VML. Top row are predefined shapes, these are built in shapes like circle or rectangle. Middle row are custom paths, constructed from the sub-elements: cubic and quadratic bezier curves, lines and elliptical arcs. Bottom row are image and text elements. Each of these basic elements needs its own converter, which you then combine into one. Early on we had two converters, one which keeps predefined elements as they were. e.g. an SVG circle to a VML circle. Another which converts all SVG shapes into VML paths e.g. an SVG circle into a VML path that’s a circle. It’s semantics, as you can create all the predefined shapes from paths. But for compatibility reasons such as transforms, we went with converting all basic SVG shapes into VML paths.
Custom paths
Early failed VML test, looks like an Etch a sketch.
Quadratic bezier curves a sub-element of paths
Chained quadratic bezier curves
More bezier'
Different ways to define an elliptical arc ( sub-element of paths ), some are working, some aren't.
Getting somewhere, lettering from a watch drawn in Illustrator.
Complex path with lots of flourishes, at this point we were testing single paths only.
SVG polygons to VML
SVG polygons to VML, this torus was generated using our 3D to SVG tool.
More 3D .obj to SVG polygons to VML
Another SVG polygon to VML test, this time with some transparency.
Multiple SVG elements to VML
This was the test we were building up to, it contains multiple paths, polygons, circles, lines etc.
All the rest of the SVG
You can paste just an SVG path into the converter, and get a VML path back, but SVG files are often more complicated. Many contain multiple paths, not just the one. They’re given a color, placed into groups, and transformed into place. There’s a bunch of assembly instructions if you like. Where possible, we wanted to convert a whole SVG file to VML, from the opening to the closing tag.
Trying to make it more than a path converter opens a can of worms. SVG and VML each have features the other doesn’t, or only partial support for some stuff. But it's still worth trying to automate some basic features, in order to make it more practical. We’re trying to convert what we can, and ignore the rest. In many cases it converts just fine, but you’ll run into issues at some point. You can work around them by editing the SVG or VML, but you have to be comfortable doing that.
Converter support v1.
We can’t convert everything SVG to VML, as there isn’t always an equivalent. But to make the converter more practical, we’ve added support for these features.
|
We can add more support but it gets a bit gnarly from here. Some SVG features only have a partial VML equivalent, or no semantic equivalent. There’s also features in the VML spec which aren’t supported in Outlook. We tried to cover the basics, and this feels like a sensible place to stop. A lot of work going forward isn't adding extra features so much as making it more robust.
Stress testing
Stress testing Dylan Smith’s collection of email marketing logos
File size comparison
With the ( above ) collection of email logo's, all but the Klaviyo logo converted in one pass, as it needed a gradient which we applied after. This test allowed us to catch optimized SVG code. This is where characters or white space get removed to reduce file size. We’ve put some precautions in for minified code, but skip it if you can. I also compared the SVG and VML file-sizes of all the logos (see slide 16 in the deck for more detail ), and they looked to be roughly the same.
We picked up on getting the stroke weight and opacity right here, the text is also SVG. ( source )
Stress testing GT Maru SVG, by Grilli Type, we had to fix rotating elliptical arcs ( part of transforms ).
Miilkiina’ logo gave us no problems, adds a lot of personality for 5kb.
Don’t think we had any issues with these
VML layout
We spent a bit of time looking at VML' layout capabilities. Like SVG, VML uses a coordinate system for layout so it's very unrestricted. It's like divs on steroids, you can put stuff anywhere. We can recreate our HTML layouts in VML, and extra stuff besides. There’s also some limited responsive design capabilities, such as stacking and making your VML assets fluid. Weird stuff, like you can place an HTML module inside a VML textbox and stick it anywhere. This is an area we need to dig into more.
Interactive SVG slider using SMIL, this whole section is an SVG.
In 2018, we made a responsive SVG slider that combined live text, raster and vector images. I realized SVG wasn’t just for displaying vectors, but was a whole alternative layout engine. So when we started playing with VML our minds went straight to layout. It's not that I expect people to start designing entire emails with VML, but you could. So its hard to ignore, even if its not likely to make it into production. There are more feasible images-off enhancements you can make, such as logos, VML image placeholders and custom type headings etc.
Outlook has a max-with of 2112px
Here we were playing around with z-order ( layer order ).
We’ve shuffled it around so the text block is in the middle.
I know it’s a mess but you get the idea, no tables and boxy layouts, images-off
Images-on, the two images are using VML chromakey.
VML textpath
We’ve added support for VML textbox, and textpath. SVG text doesn’t have a container and VML does, so you have to give it one during the conversion. The text within VML textbox can be selected and copied. It can render in other email clients unless you tell it otherwise. Other clients ignore the VML container setting it’s width and position, but will still read its contents. Textpath can’t be selected, it's type as image or decorative, text on a path also doesn't appear to be affected by darkmode.
VML textbox and textpath
Multiple lines of rotated VML text on a path
VML textbox doesn’t rotate, so you have to put your text on a path and rotate that ( line above visible for reference ). A paragraph of text spreads out around the path depending on line breaks and line height. Were also testing alignment here.
Circle path, you can also set the text to fit the shape, which would close the circle.
Same as above just with more of a custom shaped path
VML textbox
These two VML textboxes stack into a single column if the client window is narrowed.
You can put a whole HTML module within a VML textbox ( right ).
As it’s now a VML container you can place it anywhere.
Individual elements can be linked up, VML textbox can be selected and copied.
Raster images
SVG filters don’t have an equivalent in VML, but VML does have some image effects. Below we’ve adjusted the gain and gamma, to make it match the dark background.
“Bitmaps are an essential part of VML. Raster and vector data may be intermingled. Raster data may be combined with vector data by clipping the raster to a vector path. Limited transformations (chromakey, gamma, picture and black level adjustments) may be applied to raster data.” ( source )
VML image with effects applied, textbox and custom type
Fluid VML
VML text can reflow ( see paragraph above and below ), SVG text can’t and scales like an image if you try. You can probably get the textbox to be fluid, as well as other VML assets like vectors and images. We did have a fluid test working at one point with one of the Santa models, but just on the horizontal axis. Its width would squash, but not its height. Based on that I think fluid VML is likely doable, it’s one of those things we need to get back to. That along with being able to stack content, gives you some basic responsive design capabilities.
VML textbox can reflow ( see paragraph left )
Stacking VML groups
Somewhere along the way we realized that VML groups can behave like block elements, they stack as the email client window is resized ( only if you want them too ). Here we go from a four column ( four VML groups ) to two on the image below. We could also go 4,3,2,1 if we wanted.
Stacking VML groups 4 – 2
Narrow the email client window the columns center, and stack 2 × 2.
Stacking 2 – 1, we can control stacking by how elements are grouped.
Dropped to one column and centered.
Here we have three VML groups that stack as the window narrows.
Now one column and centered.
Social icons down the bottom still.
Alt text
When working with VML groups, we’ve added an 'alt text all grouped elements' checkbox to the converter. If present it’s generated from group id names ( which you can edit in order to improve your alt text if needed ), otherwise it’s left blank, alt="". We made this optional as you might only require one alt text to describe multiple groups. If I just need one description, I add it by hand on the first line:
/* Adding alt text to VML by hand with one description */
<v:group id="catlayer" alt="Black yawning cat sitting in the sun" coordsize="600,480"
style="position:static;top:0;left:-300;width:600;height:480">
Extrude
Adding shadows with VML extrude, a VML only feature.
The original flat artwork has been extruded, and looks like a plastic toy.
Known issues
These are some of the main features that might give you trouble, or just aren’t supported in Outlook. You can edit your SVG or VML to workaround them.
Thing / issue- Defs / Partial VML support
- Clip-path / No semantic equivalent
- SVG filters / No semantic equivalent
- Gradients / Messy haven’t done them
- Animation / No Outlook support
- iFrame / No Outlook support
- Mouse events / No Outlook support
- Avoid if possible / Minified code
Defs partial support
Using shapetype 30 pigs is only 13 kb, a bit of overhead from 5 kb but not 150 kb. VML shapetype allows you to define a single path, and then make instances of it. All these instances reference the same pig data, you can also change things like the color or scale etc. of each pig. Its base outline remains the same, what you do with it afterwards is up to you. SVG supports this feature but with a group of paths, VML only supports one path. So we’ve left defs ( shapetype in VML ) out of the converter, because partial support is messy. Though this doesn’t stop anyone from using shapetype as it’s supported in Outlook.
Testing defs, or Shapetype in VML.
One pig path is ~5 kb, if we wanted 30 of them you’d expect 150 kb.
30 pig instances ( 20 seen above ), 13 kb not 150 kb
Litmus’ logo
Litmus' logo is made up of ten identical shapes, we’ve drawn a path for one and defined it as a shapetype. Made 10 instances of it, rotated, and given them a different color. This reduces the file size from 4 KB to 2 KB. In SVG these are called 'Defs' or instances, and can be applied to groups of paths. In VML it can only apply to one path. As there’s only partial support it’s not in the converter, but you can apply it by hand.
Litmus logo 4 kb down to 2 kb using VML shapetype
Clip-path
A clip-path in SVG is a layer that clips everything behind it, and there’s no direct semantic equivalent to SVG clip-path in VML. This test is a VML shape element that has a background image, that is clipped by the path. It will have no effect on anything else within the composition. Instead of filling the shape with a color, we’re filling it with an image. Here we’re faking a 3D transform, the image within the shape has been edited to appear skewed, and then clipped by the path.
VML image test faking a 3D transform
Gradients
The converter doesn’t support gradients in v1, it will output the paths in a default solid color. You can then apply a gradient by hand, as we did with the Klaviyo logo above. This article on CSS background gradients written by Cosmin Popovici, has a section on VML gradients and you can view the gradient fill Microsoft doc.
Klaviyo logo solid and with VML gradient applied by hand
Interaction
All the interaction tests we’ve run have been blocked by Outlook, not completely ruling it out but the obvious stuff hasn’t worked.
Mouse eventsThis is a hard one to show in static screenshots, we’re testing mouseover interaction in VML. When you rollover parts of the watch face, either the hands rotate or change color ( from white to blue ). This is it working when viewed in IE as an .mht file ( see below ), so we know our code is right, Outlook just ignores it.
Rollover interaction working in IE not Outlook
What should happen in Outlook but only works in IE.
VML handles
Here we we’re testing VML handles, there’s no SVG equivalent, we were just curious if it worked. What should happen is you can edit your VML, by dragging the yellow nodes to alter the shape of the path. Below I altered the shape of the arrow far left. VML handles get blocked by Outlook, there's no support. Not sure what I would’ve done with this had it worked, just interested to see if it was still in there.
Testing VML handles ( no Outlook support ).
Same test working within Word
Remote loading
Here we're testing VML iframe, which allows you to load VML content externally. It would also enable support for dynamic VML content, such as personalized charts etc. Unfortunately while this worked for us in IE ( below ), it came in blank in Outlook. Unsurprisingly they've blocked it.
VML iFrame working in IE ( remote loading ), blank in Outlook. Would have meant support for dynamic content.
MHT converter
A useful tool in all this was a VML / HTML to MHT converter, we wrote for previewing VML in IE. IE doesn’t support VML anymore ( no browser does ), but you can trick it by converting your VML to MHT. There’s a ‘Click here to view in a web browser’ message that comes up in Outlook sometimes. When you click it, it displays the email including the VML in IE, from there we realized what was going on. It was particularly useful with a few of these tests that use interaction etc. While Word and IE are reliable proxies, some things work in Word / IE but not Outlook. Though generally speaking we found IE was a better proxy than Word, but we still used Word often for quick previews.
VML rendering
VML is supported in all desktop Outlook email clients, it’s currently at 9 % marketshare ( 4th ) as of May 2021. You can target only the email clients that support VML, or use MSO to drill down further. Combined vector support in email is ~ 74 %, this includes both VML and SVG. We're testing on Outlook 2010 and Windows 10 Mail on a PC, which is where all these cropped screenshots are from. We used Litmus to preview versions of Outlook we don't have. From our testing VML renders the same across all desktop Outlook email clients up to 2019.
VML support in Outlook ( Litmus )
Email marketing logo’ preview ( Litmus )
Gameboy preview ( Litmus )
VML shapetype support ( Litmus )
Stylecampaign lettering preview ( Litmus )
Win 10 Mail split
I did notice a slight rendering split between Windows 10 Mail and all the Outlooks. Mainly Win 10 doesn’t support textpath, Outlook does. Interestingly textpath doesn’t render in Word either. Beyond that vectors render the same, but I will test further.
The split with Win 10, it doesn’t support textpath ( left ), Outlooks do ( right ).
Windows 10 Mail using a slightly different Word-based renderer than Outlooks', it's solid at drawing vectors.
Darkmode
VML in Outlook Office 365, and Win 10 Mail dark mode below. I believe both do their own automatic dark mode switching ( just the background color here by the looks of it ). You can manually opt into Windows 10 Mail dark mode: ( settings / personalization / dark mode ). Colors are automatically inverted, though as you see below just the background is changed, the vector shapes aren’t affected. These tests weren’t designed for dark mode, but you can still get an idea of how VML is handled.
Windows 10 Mail has a dark mode you manually opt into, it automatically inverts colors.
Outlook Office 365 also has a dark mode ( screenshots from Litmus )
Since I published this Nicole Merlin did an in-depth write up on fixing Outlook Office 365 dark mode issues, so I’m slipping it in. The gist of it is it’s VML textbox you need to look out for, she has some cool hacks for making sure your text stays legible. VML textpath ( e.g. text on a circle ), seems to be ignored by dark mode based on what I’ve seen.
Pig textpath preview in Outlook Office 365 ( Litmus )
Vector support
For the ~ 74 % support mentioned above, I ran some SVG / VML tests in Litmus early 2021. I'm getting my stats from Emailclientmarketshare:
VML support
- Outlook 2007
- Outlook 2010
- Outlook 2013
- Outlook 2016
- Outlook 2019
- Outlook Office 365
- Windows 10 Mail
= 9 % ( May 2021, * down to 6 % Sep )
Inline SVG support
- Apple Mail 13 & 14
- OL Office 365 Mac
- Outlook 2016 Mac
- Samsung Mail 6 & 7
- iOS
- T-Online.de
= 59 %
External SVG support
- Windows 10 Mail
- Android 6
- Android 7 Outlook app
- Samsung Mail 6 & 7
- AOL Mail
- Comcast
- GMX.de
- Office 365 (web client)
- Outlook.com
- Web.de
- Yahoo Mail!
- Freenet.de
= 9 % ( iOS & Mac have dropped external SVG support ).
SVG support using both techniques ~ 65 % + 9 % for VML = ~ 74 % for vectors in email.
Inline SVG & VML = 59 % + 9 % = ~ 68 % for vectors in email.
External SVG & VML = 9 % + 9 % = ~18% for vectors in email.
You can use VML on its own, I was just interested to see where we are overall.
Also see caniemail.com for SVG support.
Thanks! - Anna
VML Resources
- SVG Spec
- VML Spec
- VML Microsoft documentation
- SVG to VML converter
- Selection of our VML tests
- Backgrounds.cm by Stig
- Buttons.cm by Stig
- SVG to VML by Mark Robbins
- Making sense of Outlook’s rendering engine by Rémi Parmentier
- Background properties in VML by Rémi Parmentier
- How to fix Outlook dark mode problems by Nicole Merlin
- Outlook VML background gradients by Cosmin Popovici