HTML Email: !mso conditional trick - html

I'm relatively new to HTML Email Development, and I'm trying to improve my understanding of HTML Email structures by dissecting HTML Emails on "reallygoodemails.com".
In my forays, I've come across four different ways to create a conditional fallback for email platforms that are NOT Microsoft Outlook.
Version 1.
<!--[if !mso]><!-->
<style>
.innerTable{
border: 1px solid black;
}
</style>
<![endif]-->
Version 2.
<!--[if !mso]><!---->
<style>
.innerTable{
border: 1px solid black;
}
</style>
<![endif]-->
Version 3.
<!--[if !mso]><!---->
<style>
.innerTable{
border: 1px solid black;
}
</style>
<!--<![endif]-->
Version 4.
<!--[if !mso]>-->
<style>
.innerTable{
border: 1px solid black;
}
</style>
<!--<![endif]-->
Can anyone tell me what version I should use and explain WHY that particular version actually works cross-platform? Like, how does the syntax of your chosen fallback trick MSO into ignoring the code?

Conditional comments are a mecanism implemented by Microsoft in Internet Explorer (up until IE9) and in Word’s rendering engine (used by Outlook 2007 and above). The idea is to hide content for the rendering engine through a regular HTML comment so that no other rendering engines will see it. I’m going to detail the syntax that I use and then I'll get back to the difference between the syntaxes you observed.
Here’s the syntax that I use to hide content from Outlook:
<!--[if !mso]><!-->
<style>
.innerTable{
border: 1px solid black;
}
</style>
<!--<![endif]-->
Let’s break this step by step and see how Outlook and other rendering engines will interpret this.
<!--: This is the opening of an HTML comment. Every rendering engine is expecting what’s next to be part of the comment and won’t display it on screen.
[if !mso]>: This is the condition for rendering engines that support conditional comments (IE, Outlook). Other rendering engines and browsers will just see this as plain text, part of the comment. But IE and Outlook will evaluate the condition. The condition here is !mso (not mso). Outlook will see this and think “Well, I am mso! I’d rather ignore everything that follows until I find the [endif] statement.”
<!-->: This closes the HTML comment opened on step 1. Outlook ignores this as it’s part of the !mso content. But other rendering engines will understand this and think “Ok, this comment is over. Better get ready to execute and display what’s next.”
<style>…</style>: This is our HTML content. It’s hidden for Outlook because it’s still part of the !mso condition. And other rendering engines will render this as normal.
<!--: This is the opening of an HTML comment (again).
<![endif]: This is the closing condition statement for rendering engines that support conditional comments (IE, Outlook). Outlook will evaluate this and think “Ok, condition time is over. Back to work then.”. Other rendering engines and browsers will just see this as plain text, part of the comment.
-->: This is the closing of the HTML comment opened on step 5. This is evaluted by all rendering engines.
Now you might be thinking: “Why did we use <!--> on step 3 and not just -->?” Well this is a nice trick at play to take in account for other rendering engines that do support conditional comments (like Internet Explorer). IE will see the !mso condition and think “Well, I'm certainly no mso. Let’s see what’s next for me!” If we were to just have a closing HTML comment (-->), IE would freak out as it’d see a closing without an opening. So that’s the trick: <!--> both opens and closes an HTML comment at the same time. We could also write this <!-- --> or <!-----> (as you noticed in your Version 2 and 3).
As for the difference between the other versions you posted, Version 1 and 2 only use <![endif]--> as a closing statement. This is correct for Outlook, but incorrect for any other rendering engines. Luckily, they render this as an HTML comment anyway. So it ends up working correctly, but it is not valid in a standard way.
So my recommendation is to always use the following syntax to hide content from The Outlooks:
<!--[if !mso]><!-->
…
<!--<![endif]-->
And if you need to show content only on The Outlooks:
<!--[if mso]>
<![endif]-->
Other ressources that might be useful:
Different conditional comments examples
Microsoft documentation about conditional comments
A blog post I wrote about Outlook rendering engine

Related

Style attribute not working in MS Outlook

What do I need?
I need to make all content of the email into a single A4 size Page.
CSS
<body style="height:297mm;width:210mm;margin-left:auto;margin-right:auto">
----email content---
</body>
when i try to viewsource email css property were already there.
Problem
when try to print from ms outlook then html content move in 2 page of which my need is 1 page.
working css in browser
when i try to print the same content from browser then im able to get html content in A4 size page.
can anyone suggest how to shrink all content into single a4 size page.
any suggestion is most welcome.
Stop looking for a reason : mail clients are very though regarding CSS properties.
When you write an e-mail, almost no CSS property is accepted.
You can find an exhaustive list here.
After having played around with it a little bit, I can tell you that the best option to send a formatted mail is to create a table and style this table with inline styling.
Good luck with that, you will need it.
I suggest you to write styles in pixels. I have a such big experience in Email markup and Microsoft Outlook really harmful.
And Im not sure that margin: auto will work properly in Outlook.
So, try to write for example:
<body style="height:500px;width:500px;">
The Solution that worked for me In Ms Outlook.
<div>
<!--[if mso]>
<v:rect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-
microsoft-com:office:word" href="http://" style="yourstylinghere;"
stroke="f" fillcolor="#556270">
<![endif>
your content
<!--[if mso]>
</v:rect>
<![endif]-->
</div>

Conditional HTML (IF/ELSE) logic

I understand that in order to display outlook-specific HTML within an email I can implement code such as:
<!--[if (gte mso 9)|(IE)]>
Welcome to the newsletter.
<![endif]-->
However, how do I implement if/else logic. For example, without using CSS classes, I need to display one section of content in Outlook and a completely different section of content in other clients.
Is this possible?
(CSS Classes have proven to be unreliable hence my requirements for conditional HTML instead).
The conditional coding IS actually the IF/ELSE statement. The issue is the ELSE part is not built in. To solve your issue, you need something to hide the content you no longer want MSO to use but show up in all other clients.
This can be handled either through conditional classes (in the if statement) OR, as you mentioned you did not want to use classes, you can use the mso-hide:all css that is only recognized by Microsoft office.
Found a great example of this for reference. Pulled from this post:
<!--[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]-->
This is a good reference on usage of mso-hide:all

HTML E-Mail conditional comment for Outlook (margin)

working on an e-mail template i noticed outlook and outlook.com strips out "margin", my solution is to add additional line for those clients like
<td height="20" valign="top"> </td>
but i would like to use margin on supported clients, so i put this in a conditional block
<!--[if mso]>
<td height="20" valign="top"> </td>
<![endif]-->
Anyone knows if ALL versions of outlook are stripping out margin or is it just some of them (newer ones?)? I read Microsoft dropped support for margin, but I didn' find any information in which version it was dropped.
do i have to use additional condition to avoid older versions of outlook rendering margin like
<!--[if (gte mso 12)]>
to only affect 2007+ for example?
Don't do that -- the idea is you find a solution for the margin that resolves everywhere your supporting. Do not hack or try to condition an email!
margin is not supported in Outlook but, padding is, so use padding!
There is also additional reach arounds you could utilize such as nesting additional tables or using small white images to recreate the space. There is always a solution that you can use across - your email will be much more stable if you find it instead of trying to hack with conditionals.
Also this is a decent reference.
Specific to outlook 2007 info.
But if you really must (sigh).. it is possible; the below is targeting Outlook 2007 specifically:
<!--[if gte mso 12]>
<style type="text/css">
/* Your Outlook-specific CSS goes here. */
</style>
<![endif]-->
the mso 9 correlates with outlook 2007 below is a list of more:
Outlook 2000 - Version 9
Outlook 2002 - Version 10
Outlook 2003 - Version 11
Outlook 2007 - Version 12
Outlook 2010 - Version 14
Outlook 2013 - Version 15
Read More about this.
Note: While this is possible, I still suspect using these will create more problems in the long wrong.
Good luck!
As per the EmailonAcid Article Outlook.com DOES Support Margins.
The fix for this is ridiculously simple. All you have to do is capitalize the "M" in Margin. That's right, changing all of your "margin" to "Margin" will cause them to work properly in Outlook.com.

Replace IE conditional statements for IE 10+

IE 10+ does not support conditional statements. This makes developing for IE 7-11 tricky becaues IE10-11 parses the content within a conditional statement rather than ignoring it. For example:
<!--[if (IE 9) | (IE 8)]><!-->
// Code here will get rendered by IE10 & IE11
<!--<![endif]-->
So, if I want to have some code that will get rendered in IE 8 & 9 only, and then some code that will get rendered in IE10, IE11 & Firefox only, how do I do it?
EDIT: Note that I am not talking about styles here; I want to support significant structural changes in my webpage. E.g.:
<!--[if (IE 9) | (IE 8)]><!-->
<div>
<div>
Test
</div>
</div>
<!--<![endif]-->
<!--[if (IE 10]><!-->
<div>
<h3>Test</h3>
</div>
<!--<![endif]-->
I got this to work on my end. It looks like the format for the conditional statement was off.
<!--[if (IE 9) | (IE 8)]>
Code here will not get rendered by IE10 & IE11
<![endif]-->
Also, what type of code are you rendering, js, css?
If you want only IE8/9 to render a different set of markup from everything else (meaning IE10+ receives the same code as all other browsers), that's entirely doable:
You need to hide the (IE 9) | (IE 8) condition from all other browsers. This means having the comment portion encapsulate the entire block of code, not just the conditional expressions.
You need to allow all other browsers to see the other condition, while preventing IE8/9 from seeing that portion.
The (IE 10) portion is fine; IE8 and IE9 will know that they don't satisfy the condition and so will not render the markup even though it isn't commented out, whereas IE10 will never see the condition regardless (and neither will any later versions), so it will render the markup as it's not being hidden in a comment.
Hence:
<!--[if (IE 9) | (IE 8)]>
<div>
<div>
Test
</div>
</div>
<![endif]-->
<!--[if (IE 10)]><!-->
<div>
<h3>Test</h3>
</div>
<!--<![endif]-->

Standard way to put running elements in CSS 3

What is the correct way to put Header and Footer in CSS 3 ?
I am reading up on http://www.w3.org/TR/css3-gcpm/ and I would like to know if the below is the correct interpretation of how to use running elements .
Running elements has the property of being shifted from the normal "flow" of the document and headers and footers need that .
That is the significant part I am trying to achieve and , otherwise there is a string-set attribute which can be used to name a section and use it elsewhere int he page margins .
I am also curious if 3rd party implementations support them ? I know of some similar markup's in some tools but I want to know if this is what CSS is trying to mean?
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Testing</title>
<style type="text/css">
div.header {position: running(header)}
div.footer {position: running(footer)}
#page{
#top-center {content: element(header)}
#bottom-center {content: element(footer)}
}
</style>
</head>
<body>
<div class="header"> HEADER </div>
<div class="footer"> FOOTER </div>
<div>
Normal Text
</div>
</body>
<html>
http://jsfiddle.net/VubtS/ - But of-course browsers won't display that since it is for paged media .
I am trying this in some HTML - PDF convertes to see how much they comply with CSS 3 but apparently none of them renders this . Is my markup correct as per the Css3 definition ?
I believe that your syntax is correct. However I am also not seeing browser support for it yet. Most of the commercial HTML to PDF tools I have looked at (Winnovation, DynamicPDF, EvoPDF, RasterEdge, wkhtmltopdf and more) use WebKit or another layout engine that does not support CSS3 Paged Media.
I think these do though ...
Prince (It uses it's own layout engine PrinceXML)
DocRaptor (It uses PrinceXML as a webservice)
RealObjects
Antenna House
Just to confirm #theChrisMarsh's answer, the syntax is correct.
I have direct experience with Flying Saucer which, although otherwise only supports CSS 2.1, includes support for CSS-3-style running elements for paged media. Browsers of course don't do anything with it because they are #media print although it might be different if you try to print (but e.g. Firefox print preview is awful as of FF 27.0).
I've always understood it that <header> should go at the top shortly after the opening of the <body> tag and <footer> should go at the bottom just before the closing of the <body> tag. Their positioning depends on how you want to lay out the site.