Get off the <table>

As I publish this I've just given a brief presentation at Litmus Live in London about building emails without tables.

I've made a good start but the code isn't really production ready just yet so I'd like to open it up to the #emailgeeks community, so others can try and build on what I've started.

Why do we use tables in email?

The short answer is Outlook.

Instead of using an HTML rendering engine to render email code Outlook uses the Microsoft Word rendering engine. This only applies to the Windows desktop version of Outlook and the Windows 10 Mail app. Outlook on Mac and Outlook.com both use HTML rendering.

So because they don't use proper HTML standards, the layout has to be built using <table> elements.

What's wrong with tables?

They use more code

In email we're limited to ~102kb of code so any reduction of code means we can include more relevant quality content.

They aren't naturally accessible

<table> elements are not designed to be used for layout so assistive technology will treat them as data table unless you add role="presentation" you can read more about email accessibility here

They don't inherit styles well

All browsers and email clients come with some basic default styling. This results in having to reset things like font settings every time a new table is added.

They can be tricky to manipulate

When building a responsive layouts you often want to move parts of the content around. This can be tricky when using tables, particularly when you sometimes don't have control of the <!DOCTYPE html>

The Code

So I'm going to focus on getting a central 600px wide container to wrap our content.

To start off with the code that will work in all other email clients;

<div style="background:red;max-width:600px;margin:0 auto;text-align:center;">  

Then to get outlook to respect the width we want we add this code

mso-element-frame-width:600px;  

At this point outlook will actually convert the <div> element into a <table>.

Currently I don't have a way to do multiple columns inside our container so to be able to add a table inside here, we add this;

mso-element:para-border-div;  

Then to centre align the container we use this;

mso-element-left:center;  

Then to stop additional content floating alongside this we add;

mso-element-wrap:no-wrap-beside;  

And that's it, you now have a 600px wide centre aligned container for you email. Here it is in it's entirety.

<div style="background:red;max-width:600px;margin:0 auto;text-align:center;  
mso-element-frame-width:600px;  
mso-element:para-border-div;  
mso-element-left:center;  
mso-element-wrap:no-wrap-beside;">  
  <!-- Content -->
</div>  

However there are still a few issues that prevent this form being production ready.

Issues to solve

As these are solved I'll try and update this article and give credit.

  • Remove blue outline
  • <body> colour for Windows 10 mail
  • Changing the background for a section
  • Background images
  • Multi column layout inside the container
  • Padding that holds the background

Get involved

Take the code above, find bugs, find solutions and get involved. I want this to be a community effort.

Add to the project on github, write up your findings on your blog, share your them in the comments below or on twitter using the hashtag #GetOffTheTable. There's also a discussion on the Litmus Community

A few resources to help get you started