responsive email design and development
DESCRIPTION
How to design and code responsive HTML emails. Presented at a UCLA Campus Web Publishers meeting on January 22, 2014.TRANSCRIPT
WHY?
STATISTICS
Source: Litmus https://litmus.com/blog/mobile-opens-hit-51-percent-android-claims-number-3-spot
Source: https://litmus.com/blog/mobile-opens-hit-44-and-outlook-com-takes-a-dive
Source: https://litmus.com/blog/mobile-opens-hit-record-high-of-47?utm_campaign=aug2013news&utm_source=newsletter&utm_medium=email
Source: Litmus https://litmus.com/blog/mobile-opens-hit-51-percent-android-claims-number-3-spot
If you’re not designing for mobile, you’re ignoring half your audience.
Source: E-Dialog http://www.e-dialog.com/pdf/smartguides/edialog_responsive_email_design_guide_2013.pdf
Source: https://litmus.com/blog/saving-email-for-later-opens-across-devices-environments
pinch + zoom
≠mobile optimized
DESIGN
Step 1 Scalable graphics
Step 2 Increase font size
TS;DR (too small; didn’t read)
scaled images +readable type
=single column responsive
Limited time? Single column
Step 3 Manage the flow of content
a
Step 4 Design for mobile viewports
Not all mobile clientssupport @media queries
Not all mobile clients scale to fit
Design for the upper left “mobile fold”
Step 5 Create large touch targets
Step 6 Communicate structure & hierarchy
Step 7 Embrace brevity
What is this and why do I care?
Step 8 Design your microcontent
Carefully choose the From: name
Shorten and front-load subject lines
CODING BASICS
HTML emails are not webpages
Deprecated code
Variable support for HTML + CSS
<table align="center" border="0" cellpadding="0" cellspacing="0"> <tr> <td>Lorem Ipsum</td> </tr></table>
Table-based layouts
<table border="0" cellpadding="0" cellspacing="0" style="width:600px;"> <tr> <td style="width:300px;">Lorem Ipsum</td> <td style="width:300px;">Lorem Ipsum</td> </tr></table>
<table border="0" cellpadding="0" cellspacing="0" style="width:600px;"> <tr> <td style="width:150px;">Lorem Ipsum</td> <td style="width:150px;">Lorem Ipsum</td> <td style="width:150px;">Lorem Ipsum</td> <td style="width:150px;">Lorem Ipsum</td> </tr></table>
<table border="0" cellpadding="0" cellspacing="0" style="width:600px;"> <tr> <td style="width:200px;">Lorem Ipsum</td> <td style="width:200px;">Lorem Ipsum</td> <td style="width:200px;">Lorem Ipsum</td> </tr></table>
Stackable tables
a
<!-- ::::::::::::::::::::::::: STACKABLE TABLE:::::::::::::::::::::::::: --><table border="0" cellpadding="0" cellspacing="0" class="stacking-table"> <tr> <td class="gutter"> </td> <td class="center">
<!-- ::::::::::::::::::::::::: NESTED TABLE :::::::::::::::::::::::::: --> <table border="0" cellpadding="0" cellspacing="0" class="two-column"> <tr> <td class="column">...</td> <td class="column">...</td> </tr> </table>
</td> <td class="gutter"> </td> </tr></table>
Nested tables
aa
<table border="0" cellpadding="0" cellspacing="0" style="width:600px;"> <tr> <td colspan="3" style="width:600px;">You will regret using this colspan!!!</td> </tr> <tr> <td style="width:200px;">Lorem Ipsum</td> <td style="width:200px;">Lorem Ipsum</td> <td style="width:200px;">Lorem Ipsum</td> </tr></table>
Avoid colspan and rowspan attributes
<!-- Fixed widths --><table border="0" cellpadding="0" cellspacing="0" style="width:600px;"> <tr> <td style="width:300px;">Lorem Ipsum</td> <td style="width:300px;">Lorem Ipsum</td> </tr></table>
<!-- Fluid widths --><table border="0" cellpadding="0" cellspacing="0" style="width:100%;"> <tr> <td style="width:50%;">...</td> <td style="width:50%;">...</td> </tr></table>
Define <table> + <td> widths
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
Doctype
<!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">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
HTML validators
<img src="..." width="150" height="100" />
Define image width + height
<!-- Symbols and Latin use entity names -->© • — é ñ
<!-- Non-Latin use entity numbers --> 激 光 這
HTML entities
.h1 { font-size:32px; line-height:115%; }
.h2 { font-size:26px; line-height:130%; }
.h3 { font-size:21px; line-height:150%; }
.h4 { font-size:18px; line-height:150%; }
.column-full { width:540px; }
.column-half { width:260px; }
.column-third { width:170px; }
.column-quarter { width:130px; }
.spacer-xl { height:50px; line-height:50px; }
.spacer-lg { height:40px; line-height:40px; }
.spacer-md { height:30px; line-height:30px; }
.spacer-sm { height:20px; line-height:20px; }
.spacer-xs { font-size:10px; height:10px; line-height:10px; }
.border { border-bottom:1px solid #aaaaaa; }
.border-thick { border-bottom:5px solid #cccccc; }
Use CSS
But inline it
/* Font styles */.text-style { font-family:"Lucida Grande", "Lucida Sans Unicode", "Corbel", "Tahoma", sans-serif; font-size:14px; font-style:italic; font-weight:bold; line-height:1.2em; text-align:left; text-decoration:underline;}
Supported CSS
/* Color styles */.color-style { background-color:#F0235B; border:1px solid #999999; color:#FFFFFF;}
Supported CSS
/* Positioning */.div-position {
float:left; position:relative; top:100px; z-index:1;
}
Unsupported CSS
/* Margins */.h1 { margin:0 0 24px; }.p { margin:0 0 10px; }
Unsupported CSS
<!-- BAD --><h1>Headers and paragraphs have default margin styles</h1><p>Not all email clients will let you override or zero them out.</p>
Avoid elements with default margins
<div class=”h1”>H1 Header</div><div class=”p”>Paragraph...</div>
<table><tr>
<td class=”h1”>H1 Header</td><td class=”p”>Paragraph...</td>
</tr></table>
Font styles on block elements
/* Vertical spacers for text spacing */.spacer-xl { height:50px; line-height:50px; }.spacer-lg { height:40px; line-height:40px; }.spacer-md { height:30px; line-height:30px; }.spacer-sm { height:20px; line-height:20px; }.spacer-xs { font-size:10px; height:10px; line-height:10px; }
Vertical spacers
<div class=”h1”>H1 Header</div><div class=”spacer-lg”> </div><div class=”p”>Paragraph...</div>
<table><tr>
<td class=”h1”>H1 Header</td><td class=”spacer-sm”> </td><td class=”p”>Paragraph...</td>
</tr></table>
Combine for flawless text layout
/* Padding */img { padding:5px; }td { padding:10px; }
/* Not fully supported on table, div or p elements */
Partially supported CSS
/* Background images */td { background-image:url("http://..."); }
Partially supported CSS
<td background="http://.../background-image.gif" bgcolor="#f6f6f6" width="200" height="200" valign="top"> <!--[if gte mso 9]> <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="width:200px;height:200px;"> <v:fill type="tile" src="http://.../background-image.gif" color="#f6f6f6" /> <v:textbox inset="0,0,0,0"> <![endif]--> <div> </div> <!--[if gte mso 9]> </v:textbox> </v:rect> <![endif]--></td>
Background image hack
/* HTML buttons */a { display:block; }
Partially supported CSS
<div> <!--[if mso]> <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="http://" style="height:40px;v-text-anchor:middle;width:200px;" arcsize="10%" strokecolor="#1e3650" fill="t"> <v:fill type="tile" src="http://i.imgur.com/0xPEf.gif" color="#556270" /> <w:anchorlock/> <center style="color:#ffffff;font-family:sans-serif;font-size:13px;font-weight:bold;">Show me the button!</center> </v:roundrect> <![endif]--> <a href="http://" style="background-color:#556270;background-image:url(http://i.imgur.com/0xPEf.gif);border:1px solid #1e3650;border-radius:4px;color:#ffffff;display:inline-block;font-family:sans-serif;font-size:13px;font-weight:bold;line-height:40px;text-align:center;text-decoration:none;width:200px;-webkit-text-size-adjust:none;mso-hide:all;">Show me the button!</a></div>
Button hack
Guides to CSS Support
Microsoft Outlook 2007, 2010, 2013...
...Your Worst Enemy
<!--[if gte mso 9]><style type="text/css">
/* Outlook specific CSS here */</style>
<![endif]-->
Conditional statements for Outlook
RESPONSIVE
Fluid gridsFluid mediaMedia queries
Source: http://moddify.com/is-android-fragmentation-for-real/
Source: http://punchcut.com/perspectives/expanding-universe-toolset-managing-screen-resolutions
Source:
Source: http://emailclientmarketshare.com/
Source: http://stylecampaign.com/blog/2012/10/responsive-email-support/
Source: http://www.campaignmonitor.com/guides/mobile/#mobile-support
@media only screen and (max-width: 599px){
...}
@media
@media only screen and (max-width: 599px){
...}
@media only screen and (max-width: 480px){
...}
Breakpoints
<meta name="viewport" content="width=device-width">
Viewport <meta>
<head> <style type="text/css">
/* Fixed Styles */ .container { ... } .column { ... } .gutter { ... }
/* Responsive styles */ @media only screen and (max-width: 599px)
{ [id=container] { ... } [class=preheader] { ... } span[class=highlight] { ... } } </style></head>
Attribute selectors
.container { width:600px; }
.column { width:560px; }
.gutter { width:20px; }
@media only screen and (max-device-width: 599px){ [class=container] { width:100% !important; } [class=column] { width:92% !important; } [class=gutter] { width:4% !important; }}
Percentage widths
<!-- Inlined for maximum compatibility with desktop/webmail clients -->.container { width:600px; }.column { width:560px; }.gutter { width:20px; }
<!-- Not inlined, thus they need !important for CSS precedence -->@media only screen and (max-device-width: 599px){ [class=container] { width:100% !important; } [class=column] { width:92% !important; } [class=gutter] { width:4% !important; }}
!important declarations
[class=column-half] img { width:100% !important; height:auto !important; max-width:300px !important;}
Fluid images
<!-- ::::::::::::::::::::::::: STACKABLE TABLE:::::::::::::::::::::::::: --><table border="0" cellpadding="0" cellspacing="0" class="stackable-table"> <tr> <td class="gutter"> </td> <td class="center">
<!-- ::::::::::::::::::::::::::::: NESTED 2-COLUMN TABLE :::::::::::::::::::::::::::::: --> <table border="0" cellpadding="0" cellspacing="0" class="two-column"> <tr> <td class="column">...</td> <td class="column">...</td> </tr> </table>
</td> <td class="gutter"> </td> </tr></table>
Multi-column layouts
.two-column { width:600px; }
.two-column .column { width:300px; }
@media only screen and (max-width: 599px){
[class=two-column] {width:100% !important;
}
[class=two-column] [class=column] {width:100% !important;display:block !important;
}}
Multi-column CSS
a
<!-- ::::::::::::::::::::::::: OUTER TABLE:::::::::::::::::::::::::: --><table border="0" cellpadding="0" cellspacing="0" class="full-column"> <tr> <td class="gutter"> </td> <td class="center">
<table class="outlook-container-FIX"><tr><td> <!-- ::::::::::::::::::::::::::::: INNER FLOATED TABLE :::::::::::::::::::::::::::::: --> <table align="left" border="0" cellpadding="0" cellspacing="0" class="column-half"> <tr> <td> <div class="outlook-spacing-FIX"> ...Content goes here </div> </td> </tr> <tr> <td> ... </td> </tr> </table>
<table class="outlook-container-FIX"><tr><td> <!-- ::::::::::::::::::::::::::::: INNER FLOATED TABLE :::::::::::::::::::::::::::::: --> <table align="left" border="0" cellpadding="0" cellspacing="0" class="column-half"> <tr> <td> <div class="outlook-spacing-FIX"> ...Content goes here </div> </td> </tr> <tr> <td> ... </td> </tr> </table> </td></tr></table>
</td> <td class="gutter"> </td> </tr></table>
Floated tables require Outlook hack
.outlook-container-FIX { width:100%;}
.outlook-spacing-FIX { mso-table-lspace:0; mso-table-rspace:0;}
.half-column { border:1px solid #FBFBF9; }
CSS for Outlook hack
Buggy!
Quoi?????
Resources
Source: https://github.com/ladyheatherly/responsive-email/blob/master/responsive-email-template.html
Source: http://briangraves.github.io/ResponsiveEmailPatterns/
Source:
Source: https://github.com/mailchimp/Email-Blueprints
Thank you!