47

UPDATE 2023: This question was originally asked in 2013 - the landscape and supported technologies have changed greatly in that time. The accepted answer is functional and effective for legacy clients, but Frank Hagenson's answer is most likely to work for a modern clientset. Please choose accordingly.


If you're like me, your eye will be twitching by the end of reading this. I don't blame you.

Our client has requested us to develop a responsive HTML email template, with two specifications:

  1. Using as few images as possible
  2. Using as many "fancy css-enabled features" as possible. Mostly, this just means rounded corners on boxes.

This question is specifically about executing the rounded corners. Gmail and Apple support CSS rounded corners, and Outlook requires vector graphics. For the remaining platforms, they're ok with using square edges.

Here's how we're detecting and executing outlook:

<!--[if mso]><v:shape>...</v:shape><![endif]-->

Works like a charm, even back to Outlook 2000. The problem is, I can't figure out how to create a fallback. Intuition says this:

<!--[if !mso]>...<![endif]-->

but it just gets ignored outright as a comment by most other email clients, and then corners are missing from the boxes altogether. I ask you, fine members of the SO community: is it possible to deploy markup for all platforms except MSO? Perhaps there's a more clever way to accomplish this that I haven't considered? Or is email HTML still too stone-age to attempt something like this?

CodeMoose
  • 2,964
  • 4
  • 31
  • 56
  • My approach is to use images for rounded corners for Outlook, then to peel them off using media queries that target pixel-ratio @media screen and (-webkit-device-pixel-ratio), screen and (-moz-device-pixel-ratio){ — then restore using CSS(3) — the VML is fine, but it's risky and more difficult to reuse the code, to QA the code and to generally see what's happening. – revelt Jul 08 '16 at 12:39

4 Answers4

63

Found a solution after much brain-wracking. Instead of this:

<!--[if mso]><v:shape>...</v:shape><![endif]-->
<!--[if !mso]>[fallback goes here]<![endif]-->

This works very well:

<!--[if mso]>
    <v:shape>...</v:shape>
    <div style="width:0px; height:0px; overflow:hidden; display:none; visibility:hidden; mso-hide:all;">
<![endif]-->

    [fallback goes here]

<!--[if mso]></div><![endif]-->

All it does is wrap the fallback in an invisible div in MSO, and deploys the vector solution instead.

Hope this helps someone in the future!

CodeMoose
  • 2,964
  • 4
  • 31
  • 56
57

This also works, without the need for the hidden div.

 <!--[if mso]>
     Outlook content
 <![endif]-->
 <!--[if !mso]> <!---->
     Non-outlook content
 <!-- <![endif]-->

The trick is to re-open the comment before closing it on the 4th line - the

<!---->

bit. If you don't do that, IE renders "-->" before the non outlook content. Other browsers don't have that problem.

Frank Hagenson
  • 953
  • 8
  • 17
  • I'm inclined to say this does work, the other one doesn't. I've used the above suggested snippet without the and that still made the code not being displayed. Yours did. Thanks!! – moojen Jun 11 '21 at 11:15
  • Only this solution worked for me too, not the accepted one. – ikoza Mar 09 '23 at 10:21
  • 1
    @moojen I'm going to leave the accepted answer in place because it was the correct solution at the time of asking. But I've added a disclaimer to the top of this question directing users to this answer in case it's more pertinent to them. Thanks for the feedback! – CodeMoose Aug 08 '23 at 19:20
  • @CodeMoose All though I understand your rationale, I would change it as to make sure that people looking now know the current status. But either way you're right :-) – moojen Aug 15 '23 at 12:43
16

Although CodeMoose's solution does hide the fallback; in my tests, it left space for where the fallback would be (I read that Outlook doesn't render overflow:hidden). That didn't work for my layout since it bumped other elements out.

After a lot of searching, I found that if you make a small modification to CodeMoose's suggestion, it'll hide your fallback and won't add any unnecessary spacing:

<!--[if mso]>
<v:shape>...</v:shape>
<![endif]-->

<[fallback goes here] style="mso-hide:all;">

By adding "mso-hide:all;" to the actual style of your fallback, Outlook will collapse and ignore your fallback code, thereby preserving your layout. And your fallback still displays fine in clients that can handle the complex CSS you used VML to try to replicate, like in Outlook for Mac.

ste7enm
  • 171
  • 1
  • 6
  • 1
    Thanks for the feedback! If you read my answer closely, you'll see `mso-hide: all;` is at the end of the style tag on the div - did that still create extra whitespace for you? I wonder if it was inheriting styles from a parent, like line-height. – CodeMoose Oct 31 '13 at 13:35
  • 10
    it's amazing that Outlook won't just freaking implement standard CSS. /bashes head against wall – ElBel Nov 12 '13 at 18:58
  • @EllenB Microsoft, not Outlook. – Alex W Jan 20 '14 at 22:20
7

I had some troubles with Outlook falling back to Times New Roman when using a custom font with @font-face declaration. Not only did I have to hide the @font-face declaration from Outlook using the conditional around it's own style block. (all other styles go in another block). I also had to double wrap my textual content in spans with the conditional tag. Just to give an example of how this technique as posted by @CodeMoose (above) works while using a custom font.

<!--[if !mso]><!-->
    <style type="text/css">    
        @font-face {
            font-family: 'Museo100';
            src: url('http://www.somesite.nl/site/fonts/museo100-regular-webfont.eot');
            src: url('http://www.somesite.nl/site/fonts/museo100-regular-webfont.eot?#iefix') format('embedded-opentype'),
                 url('http://www.somesite.nl/site/fonts/museo100-regular-webfont.woff') format('woff'),
                 url('http://www.somesite.nl/site/fonts/museo100-regular-webfont.ttf') format('truetype'),
                 url('http://www.somesite.nl/site/fonts/museo100-regular-webfont.svg#museo100') format('svg');
            font-weight: normal;
            font-style: normal;
        }
<!--<![endif]-->

First I tried to put the conditional around my "Museo300" font declaration inside the inline style but that obviously didn't work, so I had to double wrap my content into two span's with style declarations. The inner one being conditional for non MSO.

<span style="color: #00B2EB; font-family: arial, sans-serif; font-size: 14px; line-height: 19px; font-weight: normal;">
    <!--[if !mso]><!--><span style="font-family: Museo100;"><!--<![endif]-->
    Text goes here, shown in Museo in Apple mail while this method shows in Arial in Outlook (and others that do not support custom fonts  
    <!--[if !mso]><!--></span><!--<![endif]-->
</span> 

This works great in getting Outlook to show the text in Arial while Apple mail will show the text in font Museo. Other clients (like mail on Android) have a normal fallback behaviour and just show Arial.

tvgemert
  • 1,436
  • 3
  • 25
  • 50
  • 1
    This doesn't account for the fact that some versions of Outlook will actually show the webfont. Did you try [this](http://stackoverflow.com/questions/21467381/can-outlook-2010-use-a-web-font-in-an-html-email/21485767#21485767)? Note the ` – John Feb 07 '14 at 14:13
  • Thanks for the tip! Didn't try it, because I dont have Outlook '00 and '11 at hand. – tvgemert Feb 07 '14 at 14:32