If you’ve ever had the arduous task of coding up HTML email templates, you’ll be very aware of the difficulties faced in the implementation. Cross email client rendering differences and nuances are troublesome and hard to understand (and remember!). Supporting GMail, Outlook, Hotmail, iPhone etc. comes with a surprising set of issues.
The best advice you can always takeaway from this is to keep the design simple. Preferably a one column design approach, as it’ll render the most consistent results and can be made responsive relatively easily.
When developing an HTML template, I always keep the following tips & tricks in mind. I present to you a thorough list of guidelines and best practises you should strive to follow when creating HTML emails. There are also a bunch of helpful articles, resources and tools at the end, which I couldn’t have done this without.
XHTML DOCTYPE
Get going with this simple boilerplate
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Email Template</title> </head> <body> </body> </html>
Add the mobile friendly meta tag
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Head styles
GMail strips out any CSS from the style head – but for other browsers you can benefit from adding this style block to your head
<style type="text/css"> #outlook a {padding:0;} .ReadMsgBody {width: 100%;} .ExternalClass{width: 100%;} .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} table td {border-collapse: collapse;} p {padding: 0!important; margin-top: 0!important; margin-right: 0!important; margin-bottom: 0; margin-left: 0!important; } html {width: 100%;} </style>
Hotmail wraps your HTML email in a class called .ExternalClass
. So those CSS rules are specific to Hotmail/Outlook.com. They cover some quirks you’ll otherwise bump into.
Globally adding table td
should reduce the chance of unwanted 1px borders appearing.
Hotmail sometimes wraps your content in paragraph tags if it fancies – so to counter any undesired padding and margin we add the p
rule.
I don’t recall which email client the .ReadMsgBody
targets, but it must wrap our custom HTML just like the .ExternalClass
does in Hotmail – so it’s there for good measure!
body reset
Add these rules inline on the body tag
width: 100% !important; -webkit-text-size-adjust: none; -ms-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; margin: 0; padding: 0;
-webkit-text-size-adjust: none
is iPhone/iPad specific – so you could add this to a media query instead.
Background table container
Begin with a background table. This table will act as the wrapper for your inner table.
<table cellpadding="0" cellspacing="0" border="0" width="100%"> <tr> <td> <!-- inner table will go here --> </td> </tr> </table>
Also, add these styles inline to the background table above:
line-height: 100% !important; margin: 0; padding: 0;
Adding a background colour to email
If your inner table is planning to have a different background colour to the email background. Add your other background colour in these various places just to be sure.
Inside the head, where your style
block sits, add the background colour to the .ExternalClass
and .ReadMsgBody
rule, E.g.:
<style type="text/css"> #outlook a {padding:0;} .ReadMsgBody {width: 100%; background-color: #EEEEEE;} .ExternalClass{width: 100%; background-color: #EEEEEE;} /* rest is unchanged (see above) */ </style>
Add it inline on the body tag:
<body style="background-color: #EEEEEE; ... and the other stuff from earlier ...">
And finally add it to the background table as bgcolor
and as an inline style:
<table cellpadding="0" cellspacing="0" border="0" width="100%" bgcolor="#EEEEEE" style="background-color: #EEEEEE; ...">
I’ve also seen a reliable alternative for the background colour of the email, by simply setting to bgcolor of the td cell that houses the inner table:
<!-- background table --> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <tr> <td bgcolor="#EEEEEE"> <!-- ... inner table will go here --> </td> </tr> </table>
Create an inner table for content
You can now proceed to create an inner table to house all your content:
<!-- background table --> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <tr> <td> <!-- ... inner table will go here --> <table align="center" border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF"> <tr> <!-- insert td with layout here --> <td width="600" valign="top"></td> </tr> </table> </td> </tr> </table>
A width of 600 is considered sensible – and it’s advisory to set the total width within the set of td
cells, rather than on the table itself. And I’ve added a background colour for the inner table, as the background table is a shade of grey.
Use td height instead of td padding for spacing
Using the height
attributes appears to be a more reliable choice than adding padding to a td
<td width="600" height="5" valign="top"></td>
Adding different padding amount on td in same tr
Adding padding to one td
may effect all the other td
cells. To avoid this – add a table
within the td
itself, and set unique padding to that td
instead!
<!-- background table --> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <tr> <td> <!-- inner table --> <table align="center" border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF"> <tr> <td width="300" valign="top"></td> <td width="300" valign="top"> <table cellpadding="0" cellspacing="0" border="0" align="center"> <tr> <td width="300" valign="top" style="padding: 20px 0 0 0;"> <!-- padding just applied to this td --> </td> </tr> </table> </td> </tr> </table> </td> </tr> </table>
It looks a bit mental. But nested tables are the best way to go.
Align images, not float
Use the align attribute for images instead of floating them
<img src="" alt="" width="" height="" align="left" />
Image styling
Always add this styling inline on all images
outline:none; text-decoration:none; -ms-interpolation-mode: bicubic; display:block;
Image inside a link
If your image is inside of a link, add the following CSS inline
<a href="#"><img ... style="border: none; ... and other styles from above ..." /></a>
Always specify dimensions and alt attributes for images
If your images aren’t downloaded inside the clients email automatically, setting the width and height will at least keep the layout intact. Adding an alt attribute gives the viewer an idea of what images they’re missing.
<img src="..." alt="An image" width="20" height="20" />
Styling text links
Always style the anchors inline. These are the two CSS properties you’ll be most concerned with:
color: #000000; text-decoration: none;
I’ve also seen that wrapping the text in a span
proves even more reliable:
<a href="#" style="color: #000000; text-decoration: none;"> <span style="color: #000000;">Click here</span> </a>
Forget paragraph tags
I’ve found the padding, margin and line height unpredictable when using p
tags. So instead add the text directly into the td
cells and if some of the text needs specific styling – wrap it inside a span
.
<td width="300" valign="top"> Hello, <span style="font-weight: bold;">world</span>! </td>
GMail strips out the head content
If you’ve got anything within the head part of your HTML that’s important across all email clients, be aware that GMail strips the content away. That includes any CSS you may have included inside of the style
tags.
Images less than 12px in height
If a td cell contains an image less than 12px in height, Outlook can add it’s own vertical space. To avoid this set the height on the td cell, and on the image:
<td width="300" height="10"> <img src="" alt="" height="10" width="40" /> </td>
Avoid whitespace below an image
If the image is the last item in the td cell, immediately close the td cell after the image to avoid any unwanted space. So to re-write the above example correctly, we should have done this:
<td width="300" height="10"> <img src="" alt="" height="10" width="40" /></td>
Inline your CSS
If it wasn’t already apparent, inline all your CSS. The exceptions are the rules specified in the head section earlier on in this article. Everything else should be inline. There are tools to help ease this process – which I’ll link to at the end.
Add padding to each cell
You can make use of the cellpadding attribute:
<table cellpadding="10" cellspacing="0" border="0" align="center"> <tr> <td width="300" valign="top"></td> <td width="300" valign="top"></td> </tr> </table>
Avoid whitespace between td cells
Self explanatory. Yahoo and Outlook.com can add unwanted padding in some scenarios.
Avoid shorthand hex
However tempting #000
may feel, stick to long hand hexadecimal values (#000000
) for reliable rendering.
PNGs
Lotus Notes 6 & 7 don’t support 8-bit or 24-bit PNG images. So if you’re supporting that email client you’ll need to use other image formats.
Using empty td cells as spacers
This is a good technique. And it’s recommended to add some inline styles to the empty td cell, as well as a non breaking space:
<td width="200" height="10" style="font-size: 0; line-height: 0;"> </td>
max width
If you’re going with a responsive email, it’s good practice to set a max-width of 600px. Unfortunately, Outlook and Lotus Notes 8 don’t support this. However, we can use an IE conditional check in order to create a 600px wide table in these particular email clients.
<!-- background table --> <table cellpadding="0" cellspacing="0" border="0" width="100%"> <tr> <td> <!--[if (gte mso 9)|(IE)]> <table width="600" align="center" cellpadding="0" cellspacing="0" border="0"> <tr> <td> <![endif]--> <!-- inner table --> <table align="center" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 600px;"> <tr> <td width="300" valign="top"></td> </tr> </table> <!--[if (gte mso 9)|(IE)]> </td> </tr> </table> <![endif]--> </td> </tr> </table>
It might look confusing – but look over it at least three times and the structure will make sense! gte mso 9
is for Outlook 2007+, which uses Microsoft Office as its rendering engine. And IE
is for Outlook 2000-2003 & Lotus Notes, which uses the IE rendering engine too.
Apple Mail doesn’t support max width either – but it does support media queries. So if we added the class .content
to our inner table, we can set up a media query inside the head section like this:
<style type="text/css"> @media only screen and (min-device-width: 601px) { .content {width: 600px !important;} } </style>
Text doesn’t wrap in Outlook
If you need to break long words onto multiple lines, Outlook will need some encouragement:
<td width="200" style="word-break:break-all;"> abcdefghijklmnopqrstuvwxyz </td>
Outlook minimum td height
Outlook 2007 and 2010 enforce a minimum td cell height of 2px. So those 1px strips might not be so thin when they arrive in these inboxes.
Animated gifs
Outlook doesn’t support animated gifs. However, Outlook will statically show the first slide of the animated gif – so you can create a nice & easy fallback for Outlook.
Extra resources
Great tips & email client specific quirks:
http://www.liveintent.com/news/publisher-technology/best-practices-for-developing-html-email-templates/
Fantastic email boilerplate
http://htmlemailboilerplate.com/
Email client compatibility matrix
https://www.campaignmonitor.com/css/
Automatic style inlining. This will save you a massive maintenance headache:
http://premailer.dialect.ca/
And if you’re into Node – here’s a Premailer API wrapper:
https://www.npmjs.org/package/premailer-api
Adding an ‘unsupported’ background image to the body in Outlook 2007
https://www.campaignmonitor.com/blog/post/1777/body-background-images-outlook/
Brilliant set of guidelines
https://www.campaignmonitor.com/resources/will-it-work/guidelines/
Creating a simple HTML email from scratch
http://webdesign.tutsplus.com/articles/build-an-html-email-template-from-scratch–webdesign-12770
Creating a responsive email
http://webdesign.tutsplus.com/articles/creating-a-simple-responsive-html-email–webdesign-12978
Tips & tricks – handling known oddities
https://www.emailonacid.com/blog/details/C13/7_tips_and_tricks_regarding_margins_and_padding_in_html_emails
http://www.emailonacid.com/blog/details/C13/tips_and_tricks_outlook_07-13
Email testing services
https://litmus.com/
http://www.emailonacid.com/
Bulletproof email buttons
http://buttons.cm/
All round HTML email for mobile guide
https://www.campaignmonitor.com/guides/mobile/
One column design philosophy and how to code it
http://blog.fogcreek.com/responsive-html-emails-a-different-strategy/
Thanks to the active web community (as always), we’re able to produce great HTML emails against all the odds.