Principle Into Practice - Responsive Email Design - Responsive Web Design, Part 2 (2015)

Responsive Web Design, Part 2 (2015)

Responsive Email Design

Principle Into Practice

Let’s take a closer look at how to build such an email, by going through a few chunks of code that will illustrate each of the three principles. I’ll start with the broadest bit first, the outer scaffolding that forms the layout of the email.

BUILDING FLUID STRUCTURES

In all of the responsive emails I’ve built, the container table that forms the email’s outermost structure is always fluid, having its width set to 100%. Let’s pick up our email code where we left off, and add that fluid table inside bodyTable:

<table class="center" border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable">

<tr>

<td class="center">

<table class="center" border="0" cellpadding="0" cellspacing="0" width="100%" class="flexibleContainer">

<tr>

<td>

...

</td>

</tr>

</table>

</td>

</tr>

</table>

The table receives a generic class, flexibleContainer, which is used to control the email’s width across various platforms. All that’s set initially is an upper width limit, which is set via the max-width property:

/* STRUCTURAL STYLES */

.flexibleContainer{max-width:640px;}

Unfortunately, we can’t just stop there because desktop Outlook doesn’t support the max-width property, which is currently the only thing that gives our fluidly built email its main structural limit. This is where Microsoft’s conditional comments come in handy. They can be used as wrappers placed around the opening and closing sections of the table that, in this case, performs one function — providing a set width around the entire email in Outlook:

<table class="center" border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable">

<tr>

<td class="center">

<!--[if gte mso 9]>

<table class="center" border="0" cellpadding="0" cellspacing="0" width="640">

<tr>

<td class="center">

<![endif]-->

<table class="center" border="0" cellpadding="0" cellspacing="0" width="100%" class="flexibleContainer">

<tr>

<td>

...

</td>

</tr>

</table>

<!--[if gte mso 9]>

</td>

</tr>

</table>

<![endif]-->

</td>

</tr>

</table>

With this structural limit in place, we can continue to add more elaborate structures to the flexibleContainer table.

MULTI-COLUMN LAYOUTS

A basic two-column structure, a layout commonly found in email, is a good place to start, and this is where that important second bit of spongy development markup comes in, the align attribute22. We’ll add another row to the flexibleContainer table, then two tables inside of that, each aligned left and classed as leftColumn and rightColumn, respectively:

<table class="center" border="0" cellpadding="0" cellspacing="0" width="100%" class="flexibleContainer">

<tr>

<td>

...

</td>

</tr>

<tr>

<td>

<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" class="leftColumn">

<tr>

<td align="left">

<p>This is the left column.</p>

</td>

</tr>

</table>

<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" class="rightColumn">

<tr>

<td align="left">

<p>This is the right column.</p>

</td>

</tr>

</table>

</td>

</tr>

</table>

With the markup added, the only thing that needs to be done to each column is the addition of an upper width limit:

/* STRUCTURAL STYLES */

.flexibleContainer{max-width:640px;}

.leftColumn, .rightColumn{max-width:320px;}

Next, we need to resolve desktop Outlook’s problems with the align attribute. This is where the next bit of Outlook-specific markup gets added; another table, but this time containing two cells:

<table class="center" border="0" cellpadding="0" cellspacing="0" width="100%" class="flexibleContainer">

<tr>

<td>

...

</td>

</tr>

<tr>

<td>

<!--[if gte mso 9]>

<table class="center" border="0" cellpadding="0" cellspacing="0" width="640">

<tr>

<td class="center" width="320">

<![endif]-->

<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" class="leftColumn">

<tr>

<td align="left">

<p>This is the left column.</p>

</td>

</tr>

</table>

<!--[if gte mso 9]>

</td>

<td class="center" width="320">

<![endif]-->

<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" class="rightColumn">

<tr>

<td align="left">

<p>This is the right column.</p>

</td>

</tr>

</table>

<!--[if gte mso 9]>

</td>

</tr>

</table>

<![endif]-->

</td>

</tr>

</table>

With that done, the columns don’t blow out in Outlook, and with the CSS limits in place they stack neatly on small displays. The same method can be used for three- and four-column layouts as well; creating them is just a matter of adding more aligned tables and Outlook-specific structures to support them.

SEMANTIC ORDERING

A two-column layout with equal-width column structures is pretty easy to deal with, so let’s throw a couple more challenges in the mix with the addition of another two-column layout, this time consisting of a left-hand sidebar and right-hand main content area.

The biggest difference, other than the column widths, is a semantic one; by introducing a sidebar, we introduce secondary content, which means that, ideally, the sidebar should slip under the main content so that the order of importance between the two is preserved when the email stacks vertically.

The content’s semantic order is established In the markup, with the main content table written first, and the sidebar table second. Reversing each table’s visual order is then just a matter of setting their align directions:

<tr>

<td>

<table align="right" border="0" cellpadding="0" cellspacing="0" width="100%" class="mainContent">

<tr>

<td align="left">

<p>This is the main content.</p>

</td>

</tr>

</table>

<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" class="sidebarContent">

<tr>

<td align="left">

<p>This is the sidebar.</p>

</td>

</tr>

</table>

</td>

</tr>

With the mainContent table aligned right and the sidebarContent table aligned to the left, we get the visual order we want. Next, the width limits get added to each:

/* STRUCTURAL STYLES */

.flexibleContainer{max-width:640px;}

.leftColumn, .rightColumn{max-width:320px;}

.mainContent{max-width:440px;}

.sidebarContent{max-width:200px;}

Again, much like the previous two-column structure, this one requires Outlook-specific markup to make the aligned tables play nice:

<tr>

<td>

<!--[if gte mso 9]>

<table class="center" border="0" cellspacing="0" cellpadding="0" width="640">

<tr>

<td class="center" width="440">

<![endif]-->

<table align="right" border="0" cellpadding="0" cellspacing="0" width="100%" class="mainContent">

<tr>

<td align="left">

<p>This is the main content.</p>

</td>

</tr>

</table>

<!--[if gte mso 9]>

</td>

<td class="center" width="200">

<![endif]-->

<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" class="sidebarContent">

<tr>

<td align="left">

<p>This is the sidebar.</p>

</td>

</tr>

</table>

<!--[if gte mso 9]>

</td>

</tr>

</table>

<![endif]-->

</td>

</tr>

But wait, there’s more! This section’s not quite finished, because the semantic order of the main content and sidebar tables presents an issue for the Outlook-specific table; its individual cells for the main content and sidebar tables reverses the visual order of those two content areas.

The sidebar ends up on the right, since it’s second in the markup and sits inside the second table cell. Luckily, the workaround is a simple one. By using the dir attribute, along with the rtl value on the Outlook table, we can reverse the visual order of the two content sections for desktop Outlook clients:

<tr>

<td>

<!--[if gte mso 9]>

<table class="center" border="0" cellspacing="0" cellpadding="0" dir="rtl" width="640">

<tr>

<td class="center" width="440">

<![endif]-->

...

Now, when the Outlook-specific markup is rendered, the table’s cells will have their orders reversed owing to the use of the dir attribute, and the visual order of the sidebar and main content areas is restored.

All of these techniques can be used over and over again to create different layouts that remain flexible enough to adapt to a wide range of email clients, and they can also be applied to the content structures inside.

SPONGY PATTERNS

Let’s take a quick look at how the product block mentioned earlier would be put together using these same methods.

The significant bits of content in this block are the product title, image, and summary (which includes the price, a description of the product, and a button). By separating each of these three items into aligned tables, we can set it up to have a different layout on small displays. We’ll add it to the first cell of the mainContent table, since its narrower width works well for this kind of block:

<table class="center" border="0" cellpadding="0" cellspacing="0" width="100%" class="productBlock">

<tr>

<td>

<table align="right" border="0" cellpadding="0" cellspacing="0" width="100%" class="productTitle" style="max-width:270px;">

<tr>

<td align="left">

<h4>Product Title</h4>

</td>

</tr>

</table>

<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" class="productImage" style="max-width:150px;">

<tr>

<td align="left">

<img src="http://placehold.it/150x150" height="150" width="150">

</td>

</tr>

</table>

<table align="right" border="0" cellpadding="0" cellspacing="0" class="productSummary" style="max-width:270px;">

<tr>

<td align="left">

<p>$19.99</p>

<p>A short, catchy product description goes here.</p>

<a href="...">BUY NOW</a>

</td>

</tr>

</table>

</td>

</tr>

</table>

The productTitle table is first in the markup, then aligned right; then the productImage table follows and is aligned left; and finally comes the productSummary table, aligned right again. Each table then has a width limit set:

/* STRUCTURAL STYLES */

.flexibleContainer{max-width:640px;}

.leftColumn, .rightColumn{max-width:320px;}

.mainContent{max-width:440px;}

.sidebarContent{max-width:200px;}

.productTitle, .productSummary{max-width:270px;}

.productImage{max-width:150px;}

With all that done, each item stacks in an order that makes semantic and visual sense, simply because of how the specific sections of the product block were put together.

Now we can start pouring on the media query styles, to ensure our email’s layout holds together a little better and to provide a few more styling bells and whistles to clients that can support them.

REINFORCING AND ENHANCING

So far, the table structures that have been built are all given width limits via max-width, which works all right as a baseline, but doesn’t look that great in competent email clients that support modern CSS.

We’re also not accounting for occasions where max-width isn’t supported but media queries are. That sounds ludicrous, but it does happen — this is email we’re talking about. In such cases, you have to set an explicit width on each container, so that the content within still retains the layout you plan for. Taking care of all of that means writing some simple media query rule sets to apply those widths:

@media screen and (min-width:768px){

/* STRUCTURAL STYLES */

.flexibleContainer{width:640px !important;}

.leftColumn, .rightColumn{width:320px !important;}

.mainContent{width:440px !important;}

.sidebarContent{width:200px !important;}

.productTitle, .productSummary{width:270px !important;}

.productImage{width:150px !important;}

}

@media screen and (max-width:480px){

/* STRUCTURAL STYLES */

.flexibleContainer,

.leftColumn,

.rightColumn,

.mainContent,

.sidebarContent,

.productTitle,

.productSummary,

.productImage{width:100% !important;}

}

Obviously, there are more nuanced ways to do all of this, and we can provide more styles for tablets and all, but this bit doesn’t require anything fancy, so don’t worry about how primitive these look; they’re simply illustrative of the concept.

By triggering one @media at min-width:768px, the email’s structures get width limits set at desktop sizes and up. Additionally, for small display sizes, widths are changed to 100%, so everything stacks nicely.