Creating a Future-Proof Responsive Email Without Media Queries by Nicole Merlin
Creating a Future-Proof Responsive Email Without Media Queries - Envato Tuts+ Web Design Tutorial
Some of the problems
- Gmail on iOS and Android doesn't support media queries.
- you cannot target all possible devices with media queries
- you can't
align="left"
andalign="right"
tables, they won't be vertically centered
The starting html document
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- NOTE: this doctype is still the safest -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!--[if !mso]><!-->
<!-- NOTE: Hidden from Ms Outlook, targeting Windows Phones -->
<!-- NOTE: Windows Live would not show images -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!--<![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- NOTE: empty title - for Android clients -->
<title></title>
<link rel="stylesheet" type="text/css" href="styles.css" />
<!--[if (gte mso 9)|(IE)]>
<!-- NOTE: again targeting Outlook versions -->
<style type="text/css">
table {border-collapse: collapse;}
</style>
<![endif]-->
</head>
<body>
<!--NOTE: body will be stripped by the servers, use 'center' element for CSS hooks -->
<center class="wrapper">
<!-- NOTE: webkit for older mail clients, like Apple Mail 6, to add support for max-width CSS rule -->
<div class="webkit">
[content goes here]
</div>
</center>
</body>
</html>
Then the starting CSS
/* Basics */
body {
/* NOTE: margin:0 for Android Kitkat */
margin: 0 !important;
padding: 0;
background-color: #ffffff;
}
/* NOTE: cellpadding and cellspacing could be added inline (cellpadding, cellspacing, but easier to maintain here */
table {
border-spacing: 0;
font-family: sans-serif;
color: #333333;
}
td {
padding: 0;
}
img {
border: 0;
}
/* NOTE: remove unwanted padding Android 4.4 */
div[style*="margin: 16px 0"] {
margin:0 !important;
}
.wrapper {
width: 100%;
/* NOTE: center content in Yahoo mail */
table-layout: fixed;
/* NOTE: stop text resizing errors */
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
/* NOTE: for Apple Mail 6 and Outlook 2011 */
.webkit {
/* NOTE: set max width to your preferred width */
max-width: 600px;
/* NOTE: center in Yahoo mail*/
margin: 0 auto;
}
Add outside container for Outlook
This would go into
[content goes here]
aboveOutlook doesn't support
max-width
so we need to add an outlook-only container, with conditional comments.A good inliner tool should add
cellpadding="0" cellspacing="0" border="0"
to these conditional tables – or add them manually yourself.
<!--[if (gte mso 9)|(IE)]>
<table width="600" align="center">
<tr>
<td>
<![endif]-->
<table class="outer" align="center">
<tr>
<td>
[content goes here]
</td>
</tr>
</table>
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
</table>
<![endif]-->
Give the table a max-width
with css and center it for Yahoo in Chrome
.outer {
/* NOTE: a hack so Outlook.com won't strip it out (Margin:)*/
Margin: 0 auto;
width: 100%;
max-width: 600px;
}
Full-width Banner Image
This would go into
[content goes here]
above (in table.outer)
<table class="outer" align="center">
<tr>
<td class="full-width-image">
<!-- NOTE: pixel width for Outlook -->
<img src="images/header.jpg" width="600" alt="" />
</td>
</tr>
</table>
Add CSS so that the image will resize in clients other than Outlook.Match the pixel size, set elsewhere
.full-width-image img {
width: 100%;
max-width: 600px;
height: auto;
}
Single Column Layout
<tr>
<td class="one-column">
<table width="100%">
<tr>
<td class="inner contents">
<!-- NOTE: can use <p> because of Margin: 0 auto; hack above -->
<!-- NOTE: better to use h1 classname than h1 tag -->
<p class="h1">Lorem ipsum dolor sit amet</p>
<p>Maecenas sed ante pellentesque, posuere leo id, eleifend dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Praesent laoreet malesuada cursus. Maecenas scelerisque congue eros eu posuere. Praesent in felis ut velit pretium lobortis rhoncus ut erat.</p>
</td>
</tr>
</table>
</td>
</tr>
Corresponding CSS
.inner {
padding: 10px;
}
/* NOTE: Margin hack */
p {
Margin: 0;
}
a {
color: #ee6a56;
text-decoration: underline;
}
.h1 {
font-size: 21px;
font-weight: bold;
Margin-bottom: 18px;
}
.h2 {
font-size: 18px;
font-weight: bold;
Margin-bottom: 12px;
}
/* One column layout */
.one-column .contents {
text-align: left;
}
.one-column p {
font-size: 14px;
Margin-bottom: 10px;
}
Two-column Layout
<tr>
<td class="two-column">
<!--[if (gte mso 9)|(IE)]>
<table width="100%">
<tr>
<td width="50%" valign="top">
<![endif]-->
[column to go here]
<!--[if (gte mso 9)|(IE)]>
</td><td width="50%" valign="top">
<![endif]-->
[column to go here]
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
A column has to follow this structure:
<div class="column">
<table width="100%">
<tr>
<td class="inner">
[content goes here]
</td>
</tr>
</table>
</div>
NOTE on the wrapper .column div: you could
And the corresponding CSS:display: inline-block;
directly to the table
element, but then you would not be able to nest more tables inside if needed.
/*Two column layout*/
.two-column {
text-align: center;
font-size: 0;
}
.two-column .column {
width: 100%;
/* NOTE: set this to half of you base size */
max-width: 300px;
display: inline-block;
/* NOTE: you can use "top", "center", "bottom" */
/* NOTE: match this with the valign attribute on the table */
vertical-align: top;
}
You can fill a column like so
Column size is 300px with 10px on either side, so the image size 280px
<table class="contents">
<tr>
<td>
<img src="images/two-column-01.jpg" width="280" alt="" />
</td>
</tr>
<tr>
<td class="text">
Maecenas sed ante pellentesque, posuere leo id, eleifend dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
</td>
</tr>
</table>
And the CSS
.contents {
width: 100%;
}
.two-column .contents {
font-size: 14px;
text-align: left;
}
.two-column img {
width: 100%;
max-width: 280px;
height: auto;
}
.two-column .text {
padding-top: 10px;
}
Three-column Layout
You can play with the
text-align
property to define if the blocks should align to the center, left, right.Column html is same as before.
<tr>
<td class="three-column">
<!--[if (gte mso 9)|(IE)]>
<table width="100%">
<tr>
<td width="200" valign="top">
<![endif]-->
[column to go here]
<!--[if (gte mso 9)|(IE)]>
</td><td width="200" valign="top">
<![endif]-->
[column to go here]
<!--[if (gte mso 9)|(IE)]>
</td><td width="200" valign="top">
<![endif]-->
[column to go here]
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
The CSS:
/*Three column layout*/
.three-column {
text-align: center;
font-size: 0;
padding-top: 10px;
padding-bottom: 10px;
}
.three-column .column {
width: 100%;
max-width: 200px;
display: inline-block;
vertical-align: top;
}
.three-column .contents {
font-size: 14px;
text-align: center;
}
.three-column img {
width: 100%;
max-width: 180px;
height: auto;
}
.three-column .text {
padding-top: 10px;
}
The html for a three column layout is slightly different than for the two columns.You can add more three column rows inside the
td.three-column
by adding multiple rows. I mispel a
<tr>
<td class="three-column">
<!--[if (gte mso 9)|(IE)]>
<table width="100%">
<tr>
<td width="200" valign="top">
<![endif]-->
[column to go here]
<!--[if (gte mso 9)|(IE)]>
</td><td width="200" valign="top">
<![endif]-->
[column to go here]
<!--[if (gte mso 9)|(IE)]>
</td><td width="200" valign="top">
<![endif]-->
[column to go here]
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
<tr>
<td width="200" valign="top">
<![endif]-->
[column to go here]
<!--[if (gte mso 9)|(IE)]>
</td><td width="200" valign="top">
<![endif]-->
[column to go here]
<!--[if (gte mso 9)|(IE)]>
</td><td width="200" valign="top">
<![endif]-->
[column to go here]
<!--[if (gte mso 9)|(IE)]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>