
Using Flexbox in an Email
Hello everyone ! I've been playing around with Flexbox for a while. This week-end, I decided to see how it would work in an email, so I've run a few tests. I've posted an article about using flexbox in an email on my blog (in french). Here is an english translation for you email geeks.
Not every webmails or mail applications support media queries. In order to adapt an email layout from mobile to desktop, it is important to find technical solutions that don't rely on its use. And luckily, the CSS Flexible Box Layout Module (Flexbox) allows exactly that. Flexbox is, theoratically, the perfect contender to build complex layouts from mobile to desktop without media queries. I've made a few tests to see it it was also the case in practice.
The main principle of Flexbox is to apply properties on a parent element that will have an effect on its direct children. Some properties must be applied on a parent element :
display:flex
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
And other properties must be applied on its children :
order
flex-grow
flex-shrink
flex-basis
flex
align-self
If you're not familiar with Flexbox, I invite you to check out this complete guide to Flexbox at CSS-Tricks or play around on this Flexbox playground. Here is an example of an images' grid I used to make my tests.
If Flexbox's support in modern browsers is pretty good, its use still requires -webkit-
prefixes (for Safari 8 or less) or -ms-
prefixes (for IE 10). Thus, the main property display:flex
should be written like this :
display:-webkit-flex;
display:-ms-flexbox;
display:flex;
Some webmails (like Gmail or Outlook.com on mobile) don't support <style>
tags, so it's usually better to apply styles directly inline on each tag with the style
attribute. There are tons of tools to do this automatically. And this is where I hit a first difficulty to test. Absolutely every inliners I tried didn't care about these multiple declarations of the display
property, and would only keep the last one. This is the case with Premailer, but also with Mailchimp, Putsmail, Campaign Monitor or even Zurb's premailer. Here's a final version of my test email with inlined styles (adjusted by hand).
And the good news is, every properties related to Flexbox listed above (and every possible values for each one) are fully supported in the following webmails :
- Orange
- SFR
- Free (Zimbra)
- AOL
- La Poste
However, my grid example wouldn't work in so far with La Poste. My HTML code looks like this :
<div style="display:flex; flex-wrap:wrap;">
<a style="flex:1 1 auto;" href="https://flic.kr/p/9sT8ev"><img src="bed2bb71f0.jpg" alt="" /></a>
<a style="flex:1 1 auto;" href="https://flic.kr/p/npQD9i"><img src="c16031076e.jpg" alt="" /></a>
</div>
Here's the problem : the webmail of La Poste automatically wraps every <a>
tag with a <span>
. The previous HTML code is then turned into the following :
<div style="display:flex; flex-wrap:wrap;">
<span class="Object" id="OBJ_PREFIX_DWT100_com_zimbra_url">
<a style="flex:1 1 auto;" href="https://flic.kr/p/9sT8ev"><img src="bed2bb71f0.jpg" alt="" /></a>
</span>
<span class="Object" id="OBJ_PREFIX_DWT101_com_zimbra_url">
<a style="flex:1 1 auto;" href="https://flic.kr/p/npQD9i"><img src="c16031076e.jpg" alt="" /></a>
</span>
</div>
The flexbox layout then doesn't apply any more on the <a>
tags, but on the <span>
tags. This problem can be solved by applying the flex
property to any other tag than an <a>
. But this highlights a potential important problem : the slightest HTML modification done by a webmail can have huge undesired secondary effects when using Flexbox.
Now here are the webmails in which Flexbox is not supported :
- Yahoo
- Gmail
- Outlook.com
Yahoo simply and purely filters any properties related to Flexbox listed above, even the property display:flex
.
Gmail and Outlook.com also filter every properties related to Flexbox, except the property display:flex
. And in my example, this causes a huge problem because the Flexbox layout is still applied, but with its default values. Thus, without flex-wrap
, the wrapping of images no longer happen, and the layout is totally desastrous. Here's an example of the render in Outlook.com in Firefox.
But Outlook.com has another specificity. It filters every properties related to Flexbox except those using the -ms-
prefix. Flexbox will then work perfectly in Outlook.com, but only in Internet Explorer 10 or 11. Here's an example of the render of the same email in Outlook.com in IE11.
As for email applications, Flexbox works well in Apple Mail (on OS X or iOS), Android default email application (on Android 4.4 and below), Outlook app (on iOS and Android), and Thunderbird 31 (and above). Here are the results from an Email On Acid test. (Sorry Litmus, I hope you don't mind.)
As a conclusion, I'd say that Flexbox in an email unfortunately causes more troubles than it helps solving. I think it can be interesting to use, but only for problems that can't be solved otherwise. For example, the order
property allows to reorder elements visually, not matter their order in the HTML code. iOS 9 will soon supports CSS @supports
declarations. We should then be able to write the following code :
@supports(order) {
.parent {
display:flex;
}
.child-to-reorder {
order:1;
}
}
This should allow us to make some progressive enhancements, while waiting for a better support…
Nice one Rémi, good work.
Great to hear iOS9 will be supporting
@supports
too. Perfect for progressive enhancement, it's already supported on Android 4.4+, Thunderbird and AOL(dependant on browser).. So it should open up the possibilities of experimentation a huge amount :DThanks Mark ! I didn't know
@supports
worked on AOL. I guess I'll have some more tests to make about that one :)I was a little worried about it
@supports
rendering in Yahoo since their@media
support update, I though it might render the code regardless of if it 'supports' the feature or not, but from my testing it looks to be not rendering either way.Thanks Remi this was very informative :)
Does the iOS mail app support @supports() yet? I'm trying to use display:flex inside of @supports() but it doesn't seem to be working if my Litmus tests are correct. (Works in my desktop browser though!)
iOS 9 and 10 support
@supports
. Make sure your ESP is not stripping it, or feel free to share your code so we can help you.Here's my code.
.flex
is adiv
. And the children aretable
elements. I'm using MailChimp as my ESP.@supports(order) {
.flex {
display:flex;
}
This looks promising, after some test I have the same Issue like other people above. We definitely hitting the right direction, but this could get complicated at some point =/
You might see a little better compatibility by using the uppercase hack for Outlook, Display:flex; vs display:flex;