Coding HTML for emails can be a total bitch. I’m not going to give an exhaustive how-to here, but I just wanted to share a few tricks I had to learn the hard way, in case it might save you some headaches.
First, a few general rules. These rules will occasionally need to be broken, but if you start off by at least trying to follow them, you’ll give yourself a more stable foundation.
- Host all of your images online (or via a CDN/S3) and use absolute URLs. Of course.
- Use old-school tables to position all of your elements. I know you spent a lot of time weaning yourself off them and mastering div tags positioned with CSS, but email clients rarely handle that stuff properly. For email, we’ve gotta take it all back to 1998.
- When you do use CSS (which is by no means recommended against), put your styles either in-line, or in the body tag. Many email clients will chuck your head tag completely.
- Set alt attributes for all of your images and links. I’ve seen email clients discard images and links that didn’t have alt attributes.
- Explicitly setting border-collapse on your tables to collapse with CSS seems to help kill certain table spacing-related quirks.
- Validate your HTML at w3.org. Get it as close to perfectly valid as possible (necessary hacks may make perfect validity impossible).
Now there’s one thing in particular that has given me an extraordinary amount of hell when doing HTML emails, and that is background images. Particularly when it comes to Outlook’s nasty habit of chucking them.
If you’re okay with having one big background image behind everything, you can apply a background image via CSS to the body tag. That actually works in Outlook. However, put your CSS inline or within the body tag (see above). I’ve also heard that you need to set repeat-y if you go this route; that setting CSS background-repeat to no-repeat will actually lose the background image completely in Outlook. Not sure if that’s always the case or what.
The holy grail here is applying background images to table cells. It doesn’t really work in Outlook. There is, however, a hack that I’ve found, and that is the main thing I wanted to share here today:
<table width="600" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse;"> <tr> <td style="width: 600px; height: 350px; background-image: url('http://epicreviewsdotorg.files.wordpress.com/2011/05/unicorn1.jpg');"> <!--[if gte mso 9]> <v:image xmlns:v="urn:schemas-microsoft-com:vml" id="theImage" style='behavior: url(#default#VML); display: inline-block; position: absolute; width: 600px; height: 350px; top: 0; left: 0; border: 0; z-index: 1;' src="http://epicreviewsdotorg.files.wordpress.com/2011/05/unicorn1.jpg" /> <v:shape xmlns:v="urn:schemas-microsoft-com:vml" id="theText" style='behavior: url(#default#VML); display: inline-block; position: absolute; width: 600px; height: 350px; top: -5; left: -10; border: 0; z-index: 2;'> <div> <![endif]--> <table width="600" border="0" cellspacing="0" cellpadding="0" style="border-collapse: collapse;"> <tr> <td height="350" align="center" valign="top"> <p>This table in here has a bunch of stuff I want to lay over the background image...</p> </td> </tr> </table> <!--[if gte mso 9]> </div> </v:shape> <![endif]--> </td> </tr> </table>
Outlook can’t (or refuses to) render basic CSS, but it does know VML (Vector Markup Language), which is what Microsoft Office uses to position elements in Word and Powerpoint. So what we’re doing is targeting Outlook specifically, and hitting it with some VML.