Thou shalt not use <div />

Base template & reset

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>

    <style type="text/css">
      body, table, td, h1, h2, h3, h4, h5, h6, div, span, p, a, img {
        margin: 0;
        padding: 0;
        border: 0;
        outline: 0;
      }
      
      body {
        font-family: Arial, Helvetica, sans-serif;
        font-size: 15px;
        line-height: 17px;
        color: #000000;
        background-color: #ffffff;
      }

      table td {
        border-collapse: collapse;
      }

      img {
        vertical-align: top;
        max-width: 100%;
      }
    </style>
  </head>
  <body>
    <table width="100%" cellpadding="0" cellspacing="0" border="0" bgcolor="#FFFFFF" style="width: 100%; margin: 0; padding: 0; font-size: 15px; line-height: 17px; color: #000000; text-align: left; font-family: Arial, Helvetica, sans-serif; background-color: #FFFFFF;">
      <tr>
        <td valign="top" align="center">
          <table id="main" width="640" cellpadding="0" cellspacing="0" border="0" style="max-width: 100%">
            <tr>
              <td valign="top">
              
              </td>
            </tr>
          </table>
        </td>
      </tr>
    </table>
  </body>
</html>

Facts

HTML email sucks.

There are No Standards.

- Apple Mail, Outlook for Mac, Android Mail and iOS Mail use WebKit.
- Outlook 2000, 2002 and 2003 use Internet Explorer(Trident).
- Outlook 2007, 2010 and 2013 use Microsoft Word (yes, Word!).
- Web clients use their browser’s respective engine (for example, Safari uses WebKit and Chrome uses Blink).

Code like it’s 1999 and stick to tables!
also #FFFFFF instead of #FFF, padding instead of margin, background-color instead of background.

Inline styles. All CSS must also be written inside style="" attributes.

Only web safe fonts. ( Some email clients support google fonts, but put them behind a WebKit conditional media query, so that Outlook doesn’t mess them up, and make sure to declare a web safe fallback ).

@import url(http://fonts.googleapis.com/css?family=Pacifico);

/* Type styles for all clients */
h1 {
  font-family: Helvetica, Arial, serif;
}

/* Type styles for WebKit clients */
@media screen and (-webkit-min-device-pixel-ratio:0) {
  h1 {
    font-family: Pacifico, Helvetica, Arial, serif !important;
  }
}
			

Some email clients are ignoring the DOCTYPE (ex. Android 4.x) and in some cases (Outlook, I'm looking at you!) the entire HTML wrapping structure, leaving just what is inside the BODY tag.

Here is a list with what and where is supported https://www.campaignmonitor.com/css/

Tricks

Use redundant CSS, inheritance may not work.

Everything declared in pixels. (Except size attributes, those values are unitless, width="600" not width="600px").

Avoid background images, if a background image must be used, background-repeat: repeat; works for some Outlooks, otherwise try http://backgrounds.cm/

bgcolor attribute is more reliable than css background or background-color.

If inexplicable gaps appear under images, try display: block;

valign="top" on td's keeps vertical rhythm consistent.

Create space between elements using td's with a given height or width.

Make sure image sizes never exceeds its container size, by loading exact size images. Always set image dimensions inline.

Most email clients disable images by default, so an alt="" text must be added and it can be even styled.

<img src="image.jpg" width="240" height="130" style="display: block; max-width: 100%; color: #666666; font-family: Arial, Helvetica, sans-serif; font-size: 13px;" alt="This is an image!" border="0" class="img" />
			

We can’t rely on max-width: 100%; because some clients ignore it. You will also want to embed the following CSS:

@media only screen and (max-width: 620px) {
  img {
    height: auto !important;
    max-width: 100% !important;
    width: auto !important;
  }
}
			

If your buttons need to be editable (not using linked images), there is a "bulletproof" method, that uses borders.

<a href="#" target="_blank" style="display: inline-block; font-size: 16px; font-family: Helvetica, Arial, sans-serif; font-weight: normal; color: #666666; text-decoration: none; background-color: #5D9CEC; border-top: 15px solid #5D9CEC; border-bottom: 15px solid #5D9CEC; border-left: 25px solid #5D9CEC; border-right: 25px solid #5D9CEC;" class="button">Read More →</a>
			

For responsive templates, @media queries can be used inside the style tag.

For a 2 or 3 columns layout use this structure:

<td valign="top>
 <table class="column" width="33%" align="left"></table>
 <table class="column" width="33%" align="right"></table>
 <table class="column" width="33%" align="center"></table>
</td>
			

We use this, instead of a normal 2 or 3 td's inside a tr, in order to be able to stack the columns on smaller screens.
Because some email clients strip out the DOCTYPE we can't give a td, display: block;, so we do it like this:

@media screen and (max-width: 680px) {
 table[class="column"] {
  width: 100% !important;
 }
}
			

The use of attribute selectors instead of regular class/id selectors, is to prevent Yahoo from applying "mobile" style when is not necessary.

 

Usefull stuff:
http://www.w3schools.com/html/html_tables.asp
http://www.w3schools.com/css/css_table.asp
https://css-tricks.com/snippets/html/glyphs/
http://www.w3schools.com/css/css_boxmodel.asp