How to display email content in mobile clients only

Displaying text and images exclusively in mobile email clients has long stumped email designers. It's an insidious issue - just when you're making progress in Outlook, Gmail just goes ahead and displays all your mobile content, like when that person you thought you'd spend forever with goes ahead and tips your vinyl collection up and down the whole darn street. But chin up, dear friend - it looks like those dog days are now over with this CSS fix.

To provide a bit of background, the central issue when hiding content is Gmail's lack of support for the display CSS property. Gmail strips out display: none; from HTML email code, thus resulting in today's trouble. So, while it's been possible to 'trick' this email client by using display: none !important;, this makes it impossible to use display to toggle an element's visibility in a media query for mobile devices. As Chris here puts it, !important is like the sledgehammer of CSS - use it with care, as nothing can stop it when it's swinging.

Why hide content in desktop and webmail clients?

There are a couple of inventive reasons why you would want to do this, including:

  • To display links for mobile-specific content (eg. a "Download from the App Store" button)
  • When using responsive email techniques, like progressive disclosure

Both use cases have been cause for lengthy speculation in our forums, so it was no surprise that the solution was to be found there, also.

An elegant workaround

After months of to-fro, we combined a couple of approaches to hiding content in mobile and desktop clients and finally came up with a fairly lightweight solution. Lightweight, until you realise that all this is to compensate for the lack of one lousy CSS property:

<style>
/* Media query for displaying content in mobile email clients */
@media only screen and (max-device-width: 480px) { 
   .hide { max-height: none !important; font-size: 12px !important; display: block !important; }
}

...

/* CSS for hiding content in desktop/webmail clients */
.hide { max-height: 0px; font-size: 0; display: none; }
</style>

<!-- Content to hide in desktop/webmail clients, display in mobile -->
<p class="hide">Download from the App Store</p>

Hiding images makes for a more interesting scenario. Applying the .hide class to the <img> tag isn't enough - you also have to surround the image with a <div> or <span> to ensure this technique plays along with both Gmail and Outlook. For example:

<!-- Image to hide in desktop/webmail clients, display in mobile -->
<div class="hide"><img src="..." class="hide" /></div>

Terrible. However, it does the job. There are two caveats, the first being that this technique does not work in Lotus Notes 6 & 7, however if you've been around the traps for long enough, you've likely realised that nothing CSS-related does. The second is that media query support is required in mobile email clients to make elements visible. So while this technique works in iOS Mail and Android Mail (which make up the vast majority of mobile opens), you likely won't have much luck in Gmail for iOS.

Finally, a big thanks to LandoCalrissian for getting the conversation started, jeremypeter for providing a great code example and everyone else who contributed to this fix. If you have any questions or observations, be sure to share them with us on the forums, or in the comments below. And hang on to your vinyl, okay?

Posted by Ros Hodgekiss

26 Comments

  • David
    19th March

    Good job! But I have a question… Media query doesn’t works on Gmail, Outlook Express, Outlook 2003-2007, etc.. is it? So how to implement Media query for Gmail?

  • Redferret
    19th March

    @David - media queries are only used on mobile devices, in this example, content is hidden on Desktop then the media query is used to turn it on on mobiles

  • Daniel Mul
    19th March

    display: none; does not work for gmail, as far as i know ...

  • Redferret
    19th March

    @Daniel - correct! but setting the max height and gont size to 0 does work!

  • Chris LaChance
    19th March

    Media queries don’t work on Gmail mobile from what I understand as well.

  • Patrik Jensen
    19th March

    What i’ve done earlier is that i tried to avoid any images that had to be hidden. Instead i tried to design buttons et al. only using CSS and media queries. It’s not a 100% solution, maybe just a 98% solution. But it kinda did what i wanted it too.

    I started off by setting the fontsize, lineheight and height to 0px in a inline style, i then changed the color to the same as the background color and added a ID .hide to the td i was working with. This helped me hide the line and link in allmost any of the clients i tested with. Only in Outlook 07-11 did i have a smal 1px line that revealed my text and link.

    I then turned to the media queries and used !important and sat all my wanted styles in the stylesheet. That gave me an allmost “okay” result.

    But i also gained a few grey hairs along the process. I’m looking forward to put your solution to the test, because whate i made there was a mess :-)

  • Trever
    21st March

    Dah. This is why I should be blogging.

    Our team came up with a similar solution back in October. Our client wanted to display different hero images from mobile to desktop. This suddenly turned into more requests from other clients for different text, and buttons as well.

    The hack we hit upon involves a conditional Outlook statement below the internal stylesheet along with wrapping said content in a p or div tag with the necessary classes.

    So what’s the reason behind all this madness? Why can we only use the p or div element to hide content for Outlook? Have a look at this documentation written by MS back in 2007: http://msdn.microsoft.com/en-us/library/office/aa338201(v=office.12).aspx.

    In the document linked above, those wild and crazy folks at MS coined the div and p elements COREEXTENDED. COREEXTENDED refers to “Two HTML elements that support a subset of the cascading style sheets properties…DIV and P. DIV and P support a subset of Word 2007–supported cascading style sheet.”

    Roughly translated into human speak: div and p are the only elements in Outlook that you can correctly interpret “display:none” because they, and they alone, support the most CSS properties.

    You guys do make it sound a lot more simple that our solution. So I’ll have to check it out. Thanks for the great post!

  • Lindsey McFadden
    22nd March

    Wouldn’t the CSS to hide the content on Desktop/Webmail need to be inline since most mail clients strip embedded stylesheets?

  • Ros Hodgekiss
    22nd March

    @Trever - You’re very welcome, we’d love to know how you go! And yes, you should blog :)

    @Lindsey - Sorry about the confusion there, Campaign Monitor inlines the CSS code in HTML email campaigns prior to sending, which is why we’ve not inlined the code in the examples above. It may have been a little presumptuous to assume that this is common knowledge, sorry. :)

  • Erik Woods
    29th March

    @Ros - I think you should change your code or make a note about the fact that this CSS needs to be inline. Even though Campaign Monitor’s tools will force it to be inline, it is best for everyone to see how to do it outside of those tools. I thought the same thing Lindsey said.

    Also…. you may want to consider making a few other adjustments to this code so that it works in other situations. It’s hard for me to make recommendations because I’m not sure how your tools interpret media queries, but…

    You need to define media as “all” for a fix in the Gmail app:
    http://www.emailonacid.com/blog/details/C13/the_android_mail_app_and_css_class_declarations

    You need to use attribute selectors to force Yahoo! Mail to ignore media queries:
    http://www.emailonacid.com/blog/details/C13/stop_yahoo_mail_from_rendering_your_media_queries

    Again maybe CM’s tools already handle all of this for users, but I think it would be best to describe these things for other users. I often use CM’s blog as a resource for building my own emails for our clients at Campbell Ewald, but we do not use CM to blast them - for other reasons.

  • Ros Hodgekiss
    29th March

    Hi Erik, thanks for letting us know that you’d like to see the inlining side of things addressed in coding posts, it’s something to certainly think about as many of our coding posts do assume a certain level of prior knowledge. As you mention, there is a lot more detail that can be provided in regards to Yahoo! Mail hacks et al, but my fear is, where do you stop…?

    We’ll certainly keep this in mind for future posts - big thanks for the useful links, as well!

  • Erik Woods
    3rd April

    Ros,
    I understand why you may not consider ever doing this from a business standpoint. It makes more sense for you to explain to your customers how to do things in YOUR tool. I get that.

    It’s sort of like…. explaining to someone how to write pure JavaScript instead of jQuery. It’s important for some people to know how to do that. Understanding how to fix it helps to understand how to fix future problems.

    I guess it is just frustrating because I see the community - the blog and forums - as a way for me to stay on top of everything. I often share links to articles and such with other team members and it is helping to position CM as an expert in the field. Not to say that CM hasn’t already done it on their own, though.

    Just imagine how much more feedback and interaction (and ultimately, sales) CM could get if they took the time to explain the inner workings of every fix. More traffic means more eyes means more talking means…. more sales.

  • Pedro Cappelle
    18th April

    With all this attention for mobile? Can anyone divulge what they charge extra for enabling a campaign with mobile features?

  • Tommy Grimes
    18th April

    We have a banner in several of our templates that prompts the recipient to download our mobile app; either for iPhone or Android. We’ve been using nested divs, with height and width of zero specified in HTML, and “display:none;” (inline). We then use media queries to specify the appropriate background images for each div. Nested divs that need to function as buttons are wrapped with anchor tags.

    This is working well for us so far, but I always love seeing how others approach the same problem.

  • Ros Hodgekiss
    18th April

    Hi Pedro, we actually have an upcoming blog post on whether to charge for responsive, so I recommend staying tuned next week for that. It’s actually a tricky one, because responsive isn’t a ‘bolt-on extra’, per se. Boagworld has a great blog post on this, but it’s more targeted at web design, than email.

    Tommy - Awesome, thanks for sharing this! We’d love if you could post a snippet of your code in the forums, as there isn’t just one set approach. All of us could possibly learn something from you :)

  • Pavlo
    29th April

    Great article Ros!

    It’s something that I’ve been asked about, quite a few times. I’ve been using the “overflow” fix, but this is definitely a lighter way. There are a couple of caveats to using this fix and that people should watch out for, I will mention those later.

    I think the key thing I want to mention and help out with, is the use in ‘real-world’ terms. As people seem to be getting a little confused due to CM putting CSS automatically inline, and why there is a media query version.
    In this example we want to hide a telephone number on desktop but show it on mobile, this is the most common reason for the fix as hiding something for desktop using “display: hide”, still shows content in Gmail and in Outlook it shows a blank space.

    The fix and its universal use, is like so:

    <tr>
    <td class=“shownumber”  0px;  font-size: 0;  display: none;”>Tel : 0330 000 000</td>
    </tr>

    This will now hide in both Gmail and outlook; the ‘max-height + font-size’ forces the clients to shrink the space until its invisible to the naked eye. But currently it will also hide on mobile as well, so we need to override these rules with our sledgehammer CSS tag “!important”.

    As you can see I’ve added the class “shownumber”, so we are now going to select this cell and override all the rules using the media query, like so…

    @media only screen and (min-device-width: 320px) and (max-device-width: 568px) {
    td [class=“shownumber”] {
      font-size: 13px !important;
      display: block !important;
      max-height: 25px !important;  OR   max-height: none !important;
      }
    }

    You can also select the class using a class selector (like so   .shownumber). So what’s happening here is that we are saying please override the current “font-size: 0” to 13px, “display” is set to show now and   “max-height” is set to the desired size ‘25px’ or completely ignored with ‘none’ ONLY pick one.

    This will now show perfectly on mobile and hide completely on desktop.

    On to the hazards. Ouh No…... (Don’t worry we can get around those)  Yey!
    Height – You can NOT set a height on the <td> even using HTML height attribute.

    FIX – If you have a height set on your <td> then don’t worry just remove it, as remember it will be hidden anyway in desktop, but you will be able to put it back in using the media query class selector as show above.

    Bgcolor – In outlook 2003, 2002/XP, 2000, Lotus notes 8.5 and 8 there will be a 1px line due to the shrinking.

    FIX – If you have a “background-color” in your <td> then copy it to the <table> level above as “bgcolor”.

    Padding - You can NOT set padding inside the <td>, as they will leave a blank space.

    FIX – If you have padding set inside your <td> then don’t worry just remove it, as remember it will be hidden anyway in desktop, but you will be able to put it back in using the media query class selector as show above.

    Hope this helps to clear things up.

    Once again, great work CM and all who helped out.

  • Andrew
    29th June

    The above doesn’t work if you’re trying to hide a table, it only seems to work on divs or spans. If you are trying to hide something that was in a table lay it out in a div with proper CSS styling as if the renderer can read media queries it should have good CSS rendering too.

    I found that adding the following styles to the .hide class also ensured the div was hidden:

    min-height: 0px; //Gmail seems to add min-height by itself
    max-height: 0px;
    max-width: 0px;
    display: none;
    overflow: hidden;
    font-size: 0px;

  • Jono
    6th August

    Here is a follow up to the above post with a few more complex examples, tested and working in all but Outlook.com and Gmail for mobile devices.

    Show/Hide p, div, table, table in div:
    http://chsweb.me/cmRwdShwHdCmplx

  • Ros Hodgekiss
    10th August

    Hey guys, this is fantastic work - thank you Pavlo, Andrew and Jono! If anyone else wants to chime in, could you please start a new thread on our forums? Sometimes code gets lost in our comments, not to mention, we have a great community of folks contributing to issues like this there. Thanks again for all your help!

  • Vic Dinovici
    24th August

    None of the code shared here works. Does anyone know a working method to hide content on desktop and show only on mobile except using background image which doesn’t work on BB10?

  • simon
    5th November

    This post has good intentions, but gmail for iphone is still showing hidden elements. Have tried inline on the element: display: none;
    font-size: 0;
    min-height:0;
    max-height: 0;
    line-height: 0;
    padding: 0;
    mso-hide: all;
    overflow: hidden;

    and on a wrapper:

    display: none;
    font-size: 0;
    min-height:0;
    max-height: 0;
    line-height: 0;
    padding: 0;
    mso-hide: all;
    overflow: hidden;

    Gmail is laughing… doesn’t work.

  • matt
    9th November

    Hey all,

    So, the problem has been solved for hiding mobile content on the desktop, but how do I hide desktop content so it doesn’t appear on mobile?

  • Ros Hodgekiss
    9th November

    Vic - In which email client are you finding this is not working in? Also, if background images aren’t working on the BB10, why do you need to hide them in this specific client? Happy to go through this with you :)

    simon - Very unusual, would it be possible for you to contribute what you’ve found so far to this forum thread (or a new, iPhone specific one)? We’d love to work through this with you.

    matt - Your best bet is to use a media query, ie. @media screen only and {max-width: 480px} { .content { display: none; } }. Check out our Guide to Responsive Email Design for a great intro to mobile-specific content. :)

  • Al
    13th November

    Let’s just try that again.
    wrapping an image in a span or div with an inline style=“max-height:0px;font-size:0;display:none;” does not hide it in gmail’s online webmail client.

    The only way to hide an image in gmail is to give it an inline style=“display:none !important;”

    This works every time, however, unfortunately, once you put the !important on there is NO way to get it to show again in a mobile, which completely defeats the purpose.

    Works for everything except gmail which unfortunately, is a deal killer for us. Having an image that is supposed to be hidden , show up in gmail, or not show up on an iPhone is no good.

  • Karl Horky
    12th December

    Thanks for the great post Ros. Worked almost perfectly except for Gmail web view on Android phones (mine is 2.3). There the text in my div still showed up, running into other text and making it illegible.

    My solution (in addition to your styles above) was to use the color property to match the text to the background color.

    .hide { color: #ffffff; }

    @media only screen and (max-device-width: 480px) {
      .hide { color: #333333 !important; }
    }

  • Ros Hodgekiss
    13th December

    Awesome, thank you so much for sharing this! Simply “blending in” text isn’t a bad idea… Unless it’s an unsubscribe link, of course ;)

Got something to add?

Sign up for free.
Then send campaigns for as little as $9/month

Create an account