Quantcast
Channel: HTML – Code Chewing
Viewing all articles
Browse latest Browse all 21

HTML email like a ninja

$
0
0

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;">&nbsp;</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.


Viewing all articles
Browse latest Browse all 21

Trending Articles