HTML Emails: fallback for mso conditional?

2020-01-29 05:53发布

问题:

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?

回答1:

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!



回答2:

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.



回答3:

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.



回答4:

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.