CSS Grid in Email — Making fallbacks work (#EmailWeekly Redesign — Week 3)

This week’s #EmailWeekly is a couple of weeks late, as we spent a lot of time trying to improve the experience in less-robust email clients (sorry about that).

Take a look at Week 3’s email here.

Email layout fallbacks using CSS grid

In email #2 we tried out CSS grid, and found an approach that works in some devices, and falls back to a similar layout for many others thanks to the hybrid-div approach.

However there were some email clients that had a fairly poor experience, particularly Outlooks 2007, 10, 13 & 16 (which use Microsoft’s Word engine to render HTML), plus Gmail IMAP (which doesn’t read style tags) and some regional email clients like Mail RU (which read *some CSS*, seemingly at random). These don’t represent a huge segment of our audience, but we wanted to do some work here.


Let’s look at Gmail IMAP first, which is when users read non-Gmail (or non-Gsuite) email accounts using the Gmail app (referred to in #emailgeek circles as Gmail App Non Gmail Account—GANGA). The rendering engine here is effectively the old Gmail engine we’ve had to work with for years, with the main problem being it doesn’t read <style> tags at all.

Gmail IMAP (left), plus versions of Android mail that do and don’t support <style>

We spent a lot of time exploring ways to match the full experience, but every technique we tried meant significantly compromising either code structure (usually back-to-tables) or accessibility. We’re keen as part of this project to keep inline code at an absolute minimum, so the approach we landed on was to make the experience here an almost-text version, which has very minimal inline style to add some padding and font colour. These inline styles are then removed almost everywhere else using CSS in the head of the page (more difficult than it sounds, as some other email clients have a fairly avant-garde approach to CSS inheritance).

Outlooks 2007–2016

There were several times during this process where we considered hiding the email, and just putting a huge link to view online for Outlook users.

I’m joking, I’m just serious

Initially, our web-code-first approach was failing in Outlook because padding and margins don’t really work on divs, and even simple semantic code (e.g. Unordered lists) was adding weird default margins that couldn’t be removed. Whilst some css in the header was supported, it also fails pretty quickly once you start to dig into inheritance, which is frustrating as we need that to help overwrite the inline style we added for GANGA.

We tried using borders instead of padding, but the way Outlook handles them is schizophrenic. Instead, we added a few MSO conditionals to add some Outlook specific css, and a handful of flexible ghost tables. It’s frustrating to have to go back to tables, but at least they’re only in Outlook.

The layout is visually very different for these Outlook clients – each story is full width, with a white background and the overall email is fluid up to 760px width. In both GANGA and Outlook the layout reverts back to a simpler, mostly-text version, but it’s a good experience for these users, without having to overload on hacks that cause issues elsewhere, so we’re ok with that.

Optimising the Editing Experience

Elsewhere we did a lot of work making the template work smartly in Taxi, to the point where actually building an email using the template takes about 15 minutes.

Editing #EmailWeekly 136 in Taxi for Email

When we started out, we wanted to explore taking cues from social media rather than DM — one element of this is making email as easy as posting social media. When we add a story in EmailWeekly, we only need to add 4 pieces of content: the article url, the headline, a qualifying line and a background image. Really we only need 3, as the qualifying line is optional. We were able to do some smart things here with Taxi Syntax. Firstly, if no one adds a headline or qualifying line then we can take out the tags and padding that go with them, so the design adapts.

In addition, the site favicon and site domain are entirely automated from the content of the article url field, using a combination of the Google favicon tool and a bunch of liquid filters. Here’s the code:

<p><img src="http://www.google.com/s2/favicons?domain=actionrocket.co" replace-src="http://www.google.com/s2/favicons?domain={{href}}" width="16" height="16" alt="" style="display:inline;vertical-align:middle;">&nbsp;<content replace="{{ href | remove:'http://' | remove:'https://' | remove:'www.' | split:'/' | first }}">url goes here</content></p>

Incidentally if anyone knows a way to combine liquid remove: filters please let me know, I’ve not looked too much at this yet.

Also due to the Outlook issues above, it’s helpful for us to specify some background colours in multiple places — using Taxi Syntax we can make one field editable and have the value from that field appear on the containing div and on various ghost tables. The same goes for an on/off button that switches the header text & logo from black to white. So when we’re actually making the email each week, we can effect a load of code changes by editing two fields in the editor.

Where next?

We’re getting there in terms of our redesign—now we’ve got some fallbacks in place, next week we’re planning on exploring more of what CSS Grid has to offer.

We’re re-designing our weekly newsletter in public. Find out more here, subscribe here and see progress on github here.