Julie Ng

Julie Ng

Responsive Email Layouts for Gmail App

Email HTML frustrates many web designers and developers because quirks are larger and standards are fewer than standard HTML. The headaches compound when trying to create responsive emails that are not single column and fluid.

So how do we achieve this? Let’s look at the most recent UX Munich Newsletter as a case study.

Updated Content (2 October 2015)

See article A Gmail First Strategy for Responsive Emails for an updated strategy for responsive layouts in Gmail.

I. Why care about broken Gmail?

While iOS dominates email opens, Gmail is not insignificant1. And considering that it is one of the most popular email providers in the world, it is worth supporting.

Current standard practice is to force Gmail on Android to load the 600px full-width email. But what if we wanted to create responsive layout? Note I am referring to the Gmail App, not the Email App2.

Ok, so let’s aim for perfection and get started.

II. First Try: Responsive (desktop-first)

Because we can no longer force <td>s into rows with display: block !important; 3, we have to use individual tables, like so:

<!--[if mso]><table><tr><td width="50%"><![endif]-->

  <table width="300" align="left" class="col">
    <tr>
      <td>…</td>
    </tr>
  </table>

<!--[if mso]></td><td width="50%"><![endif]-->

  <table width="300" align="right" class="col">
    <tr>
      <td>…</td>
    </tr>
  </table>

<!--[if mso]></td></tr></table><![endif]-->

Note that we need a wrapper table for Outlook, which is included inside Outlook specific <!--[if mso]> comments. This markup is ignored by other email clients and browsers. Thus, it does not interfere with our responsive transforms.

Then we can transform columns to rows like so:

@media screen and max-width: 420px {
  table[class="col"] {
    display: block !important;
    width: 100% !important;
    max-width: 100% !important;
  }
}

Results

The code above works beautifully for all major email clients except Gmail. Love all the green check marks in Litmus :-)

III. Second Try: Mobile-first

If Gmail is going to post-process our markup and try to fudge responsive layouts, let’s try to adapt to that. Instead of having Gmail guess what a mobile layout is supposed to look like, let’s explicitly dictate it.

1. Full width means min-width: 100%

The speakers are aligned oddly because Gmail is fudging my 300px into some percentage. To fix this, we also need to full min-width. So remind Gmail that 100% means 100% by adding min-width:100% to our <table>.

Now the “Full Lineup” Banner and speaker tables expand the full width. But our desktop versions are showning the mobile version.

2. Override 100% for desktops

Include this CSS in the <head> to override the mobile-first layout.

.speaker {
  width: 300px !important;
  min-width: 300px !important;
}

Now we have columns. But they don’t align properly in Outlook :-(

3. Add wrapper table for Outlook

We need an extra wrapper table to create columns via <td>s for Outlook 2007/10/13. Remember we need to wrap it with <!--[if mso]> comments.

Spell everything out and use fixed widths instead of percentages for Outlook.

Now we have something that looks like this:

<!--[if mso]><table width="600"><tr><td width="300"><![endif]-->

  <table width="100%" class="speaker" align="left" style="width:100%;min-width:100%">
    <tr>
      <td>…</td>
    </tr>
  </table>

<!--[if mso]></td><td width="300"><![endif]-->

  <table width="100%" class="speaker" align="right" style="width:100%;min-width:100%">
    <tr>
      <td>…</td>
    </tr>
  </table>

<!--[if mso]></td></tr></table><![endif]-->

4. Apply a gutter to our columns

Here I apply a 20px gutter to the columns by taking 10px from each column.

.speaker[align="left"] {
  td {
    padding-left: 0;
    padding-right: 10px;
  }
}
.speaker[align="right"] {
  td {
    padding-left: 10px;
    padding-right: 0;
  }
}

Because Outlook 2007/10/13 does not understand the [attr=""] syntax, we have to add the 10px padding inline to the <td> of the wrapper table. See final code below.

IV. Final Markup

The actual markup (including more table properties) I used for the email looks like this:

<table width="600" border="0" cellpadding="0" cellspacing="0" align="center" class="wrap">
  <tr>
    <td class="content lineup">
      <% @speakers[:all].each_with_index do |speaker, i| %>

        <% if i.even? %>
        <!--[if mso]><table width="560" border="0" cellpadding="0" cellspacing="0" align="center"><tr><td width="280" valign="top" align="left" style="padding-right: 10px;"><![endif]-->
        <% end %>

        <table width="100%" border="0" cellpadding="0" cellspacing="0" align="<%= i.odd? ? 'right' : 'left' %>" class="speaker">
          <tr>
            <td align="left">
              <a href="http://2015.uxmunich.com/speakers" title="<%= speaker[:name] %>">
                <%= image_tag "/speakers/#{speaker[:photo]}", width: 120, height: 85, align: 'right', alt: speaker[:name] %>
              </a>
              <span class="name"><%= speaker[:name] %></span><br>
              <span class="role"><%= speaker[:role] %></span>
            </td>
          </tr>
        </table>

        <% if i.even? %>
          <!--[if mso]></td><td width="280" valign="top" align="right" style="padding-left: 10px;"><![endif]-->
        <% end %>

        <% if i.odd? %>
          <!--[if mso]></td></tr></table><![endif]-->
        <% end %>

      <% end %>
    </td>
  </tr>
</table>

Note ruby arrays are zero-indexed, which is why all even columns are aligned left and all odd columns are aligned right.

V. Conclusion

We don’t have to force a full width email to the Gmail app. If we try a mobile-first approach, it actually works well enough across most email clients.

While the Litmus test shows a very broken Gmail version in their Android 4.2 (Jelly Bean) simulator, it actually works fine for me on my Android 4.4.4 (KitKat) phone. My Jelly Bean test phone is currently on loan this week. Next week I’ll check if it works.

No perfect alignment in Gmail

The new speaker photos are floated right on both desktop and mobile. So it’s not centered on the smaller screen sizes:

Gmail: Image still floated and not centered

Personally, I can live with that.

Yahoo shows mobile version

While creating this email, I discovered that Yahoo inlines whatever CSS you include, but cannot override <table width="100%"> properties with width: 270px !important. So, as a result both Gmail and Yahoo receive mobile versions of the Email on the web. That is a compromise I was willing to make.

Currently I’m wracking my brain on how to get around this.

Update (3 March 2015)

Today Yahoo Mail fixed their media query bug, so the problem described above no longer occurs. Now Yahoo Mail shows the desktop version.

But the .speaker[align="left"] selector does not work in Yahoo mail, so the column gutters are off. I originally wrote those selectors, assuming I would not need to account for Yahoo. Now to correct that, I would need an additional class added by ruby to target the correct tables, for example .speaker-left and .speaker-right.


  1. Gmail accounted for 17% of opens and Gmail Andoird 7% in January 2015 according to Litmus Labs: Email Client Market Share

  2. Gmail vs Email on Android

    Before Android v5.0 (lollipop) there were two apps: Email and Gmail. The Email app worked like most mobile email clients and understands media queries. In contrast, the Gmail App loads a gmail-post-processed version, killing all your non-inlined styles and media queries.

  3. Starting with Android 4.3 (mid-2013), this technique stopped working. See my explanation for the changes to Antwort v1.0 for details.