In this tutorial I will show you how to create a simple responsive HTML email which will work in every email client, including all the new smartphone mail clients and apps. It uses minimal media queries and a fluid width approach to ensure maximum compatibility.
Popular HTML Email Templates on Envato Elements
If you’re looking for a ready-made, professional solution, grab one of our popular HTML email templates on Envato Elements. We have hundreds of responsive options all included with your Elements membership, with easy to customize features to get you started.

Not what you’re looking for? No problem, this tutorial will teach you how to build your own.
What We’re Building
Here’s the responsive HTML email we’ll be building, feel free to fork the pen and use it in your own work. Bear in mind that when we’re viewing this template through a web browser we’re much less likely to run into problems than with email clients.
Media Queries: Only Half the Solution
There was a time when media queries were quite enough to get responsive emails working in iOS and Android mail applications, both of which support media queries.
Since then, there has been a proliferation of mail applications created for both iOS and Android platforms, with varying degrees of support for responsive email development methods.
Most notable is the latest update to the Gmail app for Android, which is twice as popular as the default mail app for Android users (which now comprise 11% of total opens). It has never supported media queries, and still doesn't, however it now scales down your emails by compressing the size of the outer table to fit within the viewable area of the screen. It's difficult to control and, when your entire email relies on media queries to display properly on mobile, generates some very unpleasant results.
Why Fluid Is the New Black
The good news is that you can design and build an email that will look excellent in every mail app, including those that don't support media queries. You can do this by using a fluid layout.
There are, however, a few design compromises that you have to make. Those lovely equal column layouts that stack to a single column don't work so well using this method. If you can learn to live without them, there are some very functional designs that can work extremely well.
Here’s what we'll be creating today:

Getting Started
Ok, let’s start off with our blank canvas.
<!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"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>A Simple Responsive HTML Email</title> <style type="text/css"> body {margin: 0; padding: 0; min-width: 100%!important;} .content {width: 100%; max-width: 600px;} </style> </head> <body yahoo bgcolor="#f6f8f1"> <table width="100%" bgcolor="#f6f8f1" border="0" cellpadding="0" cellspacing="0"> <tr> <td> <table class="content" align="center" cellpadding="0" cellspacing="0" border="0"> <tr> <td> Hello! </td> </tr> </table> </td> </tr> </table> </body> </html>
What we are creating here is our basic page with its header
, doctype
and container table with a background colour applied (to both the body and a big wrapper table, since styling of the body tag isn't fully supported). For more information on this basic setup, see Build an HTML Email Template from Scratch.
I’ve then added our main content table to the centre with a class of 'content'.
Pay Attention
Note: You will notice that in this tutorial I'm going to be placing CSS in the head of our HTML email document. I generally place styles in the head when I am going to re-use them, and keep one-off styles inline.
Important: Whenever you use CSS rules in the head of your document, you must use a tool to bring it all inline at the end of the process. If you use a service such as MailChimp or Campaign Monitor, they will automatically offer to bring your styles inline for you when you import your design. You must do this because the some clients, such as Gmail, will ignore or strip out your <style>
tag contents, or ignore them. You can also use a tool such as Premailer to bring your CSS inline. If you use Premailer or a similar tool, remember to take out your media queries before processing (since we want them to remain intact), then re-insert them at the end. MailChimp and Campaign Monitor automatically take care of this for you.
Hiding Mobile Styles From Yahoo!
You will notice that the body tag has an extra attribute. Yahoo Mail loves to interpret your media queries as gospel, so to prevent this, you need to use attribute selectors. I find the easiest way to do this (as suggested by Email on Acid) is to simply add an arbitrary attribute to the body tag. I use the suggested 'yahoo' but it could be anything you like:
<body yahoo>
You can then target specific classes by using the attribute selector for your body tag in the CSS.
body[yahoo] .class {}
Two Tricks to Master the Fluid Method
As you can see, our 'content' table is set to be 100% wide so that it will be fluid and take up the full width of smartphone and tablet screens. We'll also set a maximum width of 600px to avoid the email taking up the the entire screen on bigger devices.
There are now two slightly tricky things that we need to address to ensure that everything displays as planned across all email clients. These two fixes are thanks to Tina Ye's excellent tutorial on this method which is available over at FogCreek Blog.
1. Overcoming the Lack of Max-Width Support
Unfortunately, max-width
is not supported by all email clients. In order to get our email to display properly in Outlook and Lotus Notes 8 & 8.5, we need to wrap each table in some conditional code which creates a table with a set width to hold everything in. It targets IE (which is the rendering engine used by Lotus Notes) and Microsoft Outlook.
We'll wrap our table in some conditional code:
<!--[if (gte mso 9)|(IE)]> <table width="600" align="center" cellpadding="0" cellspacing="0" border="0"> <tr> <td> <![endif]--> <table class="content" align="center" cellpadding="0" cellspacing="0" border="0"> <tr> <td> Hello! </td> </tr> </table> <!--[if (gte mso 9)|(IE)]> </td> </tr> </table> <![endif]-->
2. A Fix for Apple Mail
Weirdly, Apple Mail (normally a very progressive email client) doesn't support the max-width property either. It does support media queries in HTML emails though, so we can add one that tells it to set a width on our 'content' class table, as long as the viewport can display the whole 600px.
<style type="text/css"> @media only screen and (min-device-width: 601px) { .content {width: 600px !important;} } </style>
Creating the Header
Now we'll add the first row of our table — the header. Add the following to style to the row that we already created:
<td class="header" bgcolor="#c7d8a7"> Hello! </td>
And then in your CSS, add the padding for the header:
.header {padding: 40px 30px 20px 30px;}
Adding the First Responsive Row
Now we are going to create our very first responsive row. The way we do this is to create two tables that 'float' next to each other by using the 'align' HTML property.
Left Column
Replace our little "Hello!" Greeting with the following:
<table width="70" align="left" border="0" cellpadding="0" cellspacing="0"> <tr> <td height="70" style="padding: 0 20px 20px 0;"> <img src="images/icon.gif" width="70" height="70" border="0" alt="" / > </td> </tr> </table>
We create our 70px table and also add some padding which will act as our gutter between the two columns. The padding on the bottom will add vertical breathing room when the two columns stack on mobile.
Right Column
We'll create the right column by again aligning a table to the left. This table is going to be 445px wide, which will leave us 25px to spare on the right hand side. This very is important because Outlook will automatically stack your tables if there isn't at least 25px to spare on any given row.

As long as you allow at least 25px of breathing room, your tables will behave as expected.

Stop! Alternative Tip for Tricking Outlook
To get around this quirk, you could also use conditional code to trick Outlook into thinking that you have closed a cell and opened a new one. After the closing tag of your first table, and before the opening table tag for your second, simply add:
<!--[if mso]> </td><td> <![endif]-->
Carry on..
On the wider, right-hand table, we're going to use the same approach we used on our container table, which involves creating a class and adding the conditional wrapper code too. We want this table to be 100% wide on mobile, where it will pop down below the table on the left.
<!--[if (gte mso 9)|(IE)]> <table width="425" align="left" cellpadding="0" cellspacing="0" border="0"> <tr> <td> <![endif]--> <table class="col425" align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 425px;">style="width: 100%; max-width: 425px;"> <tr> <td height="70"> </td> </tr> </table> <!--[if (gte mso 9)|(IE)]> </td> </tr> </table> <![endif]-->
Here you can see that I have created a class called 'col425' for this table, our 425px wide column. I've wrapped the table in the conditional code that will enclose it in a 425px wide table. We then add our class to the Media Query that we created for Apple Mail too.
.col425 {width: 425px!important;}
Now inside our cell we'll add the styled heading.
<table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td class="subhead" style="padding: 0 0 0 3px;"> CREATING </td> </tr> <tr> <td class="h1" style="padding: 5px 0 0 0;"> Responsive Email Magic </td> </tr> </table>
I've added some classes to each cell for styling, as well as some styles I'll be using for other text types later on:
.subhead {font-size: 15px; color: #ffffff; font-family: sans-serif; letter-spacing: 10px;} .h1 {font-size: 33px; line-height: 38px; font-weight: bold;} .h1, .h2, .bodycopy {color: #153643; font-family: sans-serif;}
Our header is now complete, and you can see below how the two columns will stack on mobile. (To preview this while you work, you'll need to temporarily comment out the min-device-width media queries, because they are enforcing a fixed width on desktop).

Creating the Single Column Text Row
To create a single column text row, we simply add a new row to our '.content' table. We'll add an 'innerpadding' class to these rows with some reusable padding values. We'll also add a class of 'borderbottom' to apply a border to each row.
<tr> <td class="innerpadding borderbottom"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td class="h2"> Welcome to our responsive email! </td> </tr> <tr> <td class="bodycopy"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tempus adipiscing felis, sit amet blandit ipsum volutpat sed. Morbi porttitor, eget accumsan dictum, nisi libero ultricies ipsum, in posuere mauris neque at erat. </td> </tr> </table> </td> </tr>
Our CSS for this section:
.innerpadding {padding: 30px 30px 30px 30px;} .borderbottom {border-bottom: 1px solid #f2eeed;} .h2 {padding: 0 0 15px 0; font-size: 24px; line-height: 28px; font-weight: bold;} .bodycopy {font-size: 16px; line-height: 22px;}
Creating the Double Column Article
Now we'll create a responsive row exactly like our header, but with slightly different dimensions so that we can have a larger image.
<tr> <td class="innerpadding borderbottom"> <table width="115" align="left" border="0" cellpadding="0" cellspacing="0"> <tr> <td height="115" style="padding: 0 20px 20px 0;"> <img src="images/article1.png" width="115" height="115" border="0" alt="" /> </td> </tr> </table> <!--[if (gte mso 9)|(IE)]> <table width="380" align="left" cellpadding="0" cellspacing="0" border="0"> <tr> <td> <![endif]--> <table class="col380" align="left" border="0" cellpadding="0" cellspacing="0" style="width: 100%; max-width: 380px;"> <tr> <td> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td class="bodycopy"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tempus adipiscing felis, sit amet blandit ipsum volutpat sed. Morbi porttitor, eget accumsan dictum, nisi libero ultricies ipsum, in posuere mauris neque at erat. </td> </tr> <tr> <td style="padding: 20px 0 0 0;"> <table class="buttonwrapper" bgcolor="#e05443" border="0" cellspacing="0" cellpadding="0"> <tr> <td class="button" height="45"> <a href="#">Claim yours!</a> </td> </tr> </table> </td> </tr> </table> </td> </tr> </table> <!--[if (gte mso 9)|(IE)]> </td> </tr> </table> <![endif]--> </td> </tr>
We've added a button here with the class 'buttonwrapper'. It contains a padded cell with a background colour set, and then a text link inside. I prefer to use this method as it allows you to have fluid width buttons which is very useful when creating a reusable template, where the width of every button will be different each time it is used. If you have a fixed width for your buttons you may prefer to use the Bulletproof Button Generator over at Campaign Monitor.
Our styles for the button:
.button {text-align: center; font-size: 18px; font-family: sans-serif; font-weight: bold; padding: 0 30px 0 30px;} .button a {color: #ffffff; text-decoration: none;}
As well as our set width for this new class 'col380', we'll add our size to our list of styles to take care of Apple Mail. It now looks like this:
@media only screen and (min-device-width: 601px) { .content {width: 600px !important;} .col425 {width: 425px!important;} .col380 {width: 380px!important;} }

Creating the Single Column Image
This is a very simple row; we'll simply set an image to be 100% of the width of the email and make sure its height is set to be automatic using CSS.
<tr> <td class="innerpadding borderbottom"> <img src="images/wide.png" width="100%" border="0" alt="" /> </td> </tr>
In our CSS:
img {height: auto;}
Creating the Final Plain Text Row
Finally we'll add a row of text without the border on the bottom:
<tr> <td class="innerpadding borderbottom"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tempus adipiscing felis, sit amet blandit ipsum volutpat sed. Morbi porttitor, eget accumsan dictum, nisi libero ultricies ipsum, in posuere mauris neque at erat. </td> </tr>
Creating the Footer
To create the footer, we'll add a new row with a table inside. One of the rows will contain another table for our social media icons.
<tr> <td class="footer" bgcolor="#44525f"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td align="center" class="footercopy"> &reg; Someone, somewhere 2013<br/> <a href="#"><font color="#ffffff">Unsubscribe</font></a> from this newsletter instantly </td> </tr> <tr> <td align="center" style="padding: 20px 0 0 0;"> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td width="37" style="text-align: center; padding: 0 10px 0 10px;"> <a href="http://www.facebook.com/"> <img src="images/facebook.png" width="37" height="37" alt="Facebook" border="0" /> </a> </td> <td width="37" style="text-align: center; padding: 0 10px 0 10px;"> <a href="http://www.twitter.com/"> <img src="images/twitter.png" width="37" height="37" alt="Twitter" border="0" /> </a> </td> </tr> </table> </td> </tr> </table> </td> </tr>
We’ll add the requisite styles for our footer to the CSS:
.footer {padding: 20px 30px 15px 30px;} .footercopy {font-family: sans-serif; font-size: 14px; color: #ffffff;} .footercopy a {color: #ffffff; text-decoration: underline;}
Optimising Buttons for Mobile
On mobile, it's ideal if the whole button is a link, not just the text, because it's much harder to target a tiny text link with your finger. Because it's not possible to have this work on all desktop clients (padding isn't fully supported on <a>
tags), it's something that I add to the mobile version using media queries.
We'll have to strip the colour from the <td>
to which it is currently applied, and then apply it back to the <a>
tag along with lots of padding.
I will use both max-width
and max-device-width
in this media query in an attempt to avoid a bug in Outlook.com on IE9.
@media only screen and (max-width: 550px), screen and (max-device-width: 550px) { body[yahoo] .buttonwrapper {background-color: transparent!important;} body[yahoo] .button a {background-color: #e05443; padding: 15px 15px 13px!important; display: block!important;} }
Now when you tap anywhere on the coloured button on mobile, it's a link!
Further Enhancements With Media Queries
If you wanted to, you could now start making enhancements to your HTML email layout by applying class names to elements that you wish to control, and then creating the new rules inside the media query we just created above.
As an example, we'll turn our unsubscribe link into a button, by adding a class to the link:
<a href="#" class="unsubscribe"> <font color="#ffffff">Unsubscribe</font> </a> <span class="hide">from this newsletter instantly</span>
and adding the following CSS to the media query:
body[yahoo] .unsubscribe {display: block; margin-top: 20px; padding: 10px 50px; background: #2f3942; border-radius: 5px; text-decoration: none!important; font-weight: bold;}
body[yahoo] .hide {display: none!important;}

You could also target the .innerpadding, .header and .footer classes to reduce the amount of padding on clients that support media queries.
Test and Go!
Finally, as always, make sure you validate (using the W3C validator — you should only get one error for the proprietary 'yahoo' attribute on the body tag) and test really well using live devices and a web preview service like Litmus or Email on Acid.
Enjoy creating responsive emails that look great in every email client!
Download Email Templates
If you need more options, then one of our responsive email templates may be just what you need. Subscribe to Envato Elements and you’ll be given unlimited access to hundreds of customizable email templates, as well as stock photography, icons, graphics, and many other creative assets for your projects.
- Campaign Monitor18 Great Campaign Monitor Templates for Email and NewslettersBrittany Jezouit
- MailChimpBest Mailchimp Templates to Level Up Your Business Email Newsletter 2021Brad Smith
- MailChimpMastering MailChimp: Best Templates and Email Tips for MailChimp NewslettersBrittany Jezouit
Learn More About HTML Email
To take what you’ve learned to the next level! Check out our Mastering HTML Email learning guide for more tutorials on HTML email templates, email design, coding responsive email, accessibility, marketing, transactional email, email service providers (ESPs), development workflow tips, and more!
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post