Make your email interactive in Gmail by using CSS attribute selectors

Update Oct 2016: With the new responsive email update, this technique no longer works in Gmail. It was a good run.

A few days back I posted the article Gmail Supports the Style tag!… Well sort of when I discovered that you could simulate CSS class selectors in Gmail by targeting attributes that Gmail does not strip such as the title attribute.

In this article I’ll delve into the nitty gritty of what I’ve found concerning this technique.

Can’t wait to see interactive email in Gmail?
Try out the Image Carousel for Email Tool.

Below is the code of the previous article showing a hoverable box. I also added a pair of class selectors (.divbox) and attributes (class=”divbox”) to make this example work with the other email clients such as Yahoo! Mail (Yahoo! Mail strips attribute selectors). I also changed it to use the lang attribute instead of title which I will go into more detail later. These articles explain the different types of attributes as well as attribute selectors.



gmail-hover

With a combination of class and attribute selectors, we’re now able to create interactive email content for all major email clients except for the lone holdout – Outlook 2007/2010/2013!

As you can see from the following code block, Gmail is very strict on single selectors, stripping out pseudo-classes as well as attribute selectors. However by adding a universal (*) selector before your style, we are able to use both pseudo-classes such as :hover as well as attribute selectors.

Here’s a summary of how Gmail processes CSS in a style tag (in the <head> of the email).


A word of warning. Rémi Parmentier noticed that having nested @ declarations (ie, a @font-face or @import declaration within a @media query) might cause Gmail to toss out the whole <style> block and Mark Robbins noticed that Gmail might truncate the styles if they are too long. So the suggestion is to put the Gmail specific styles in its own <style> block at the top of your CSS declarations.

Try it for yourself

I’ve updated the Rollover Image Tool to support Gmail. Go ahead and create your own rollover images for email!

gmail-rollover

Why use the lang attribute?
(see update for why I now prefer the summary attribute).

Gmail strips class and id attributes from all elements but leaves some other attributes intact: style, title, lang, width, height, alt, href.

Since href and alt are not technically legal attributes for divs I decided not to use them even though you could if you wanted to. A prime candidate would be title – however title comes with one side-effect – when the user hovers the cursor over the element, the title would be visible.

I chose the lang attribute because it is a universal attribute (valid for all elements) that is not visible when hovered over. Naturally we’re not using this attribute for its intended purpose – but there’s a technical exception in the HTML specifications that allow us to use it this way. By pre-pending the attribute value with an “x-”, this signifies that the lang attribute is not meant to be meaningful to the client and as far as I know, no email client currently processes the lang attribute anyways.

Update: Eric Lepetit (@ericlepetitsf) found other attributes that can be used as well – char and summary – I like summary since its pretty unencumbered. Rémi Parmentier prefers the aria-labelledby attribute . In addition, Rémi discovered a way to only exclusively target Gmail webmail by testing for the Google proxy image.

Breakdown

Here’s a total breakdown of all the styles I’ve tried and found working in Gmail:

    The following works in Gmail:
    * E[foo]
    * E[foo="bar"]
    * E[foo~="bar"]
    * E[foo^="bar"]
    * E[foo*="bar"]
    * E[foo$="bar"]
    * E:hover
    * E:link
    * E:visited
    * E:active

    E F
    E > F
    E + F
    E ~ F

Gmail even allows media queries (@media) and keyframes (@keyframe). Unfortunately, Gmail strips all animation related styles and thus, we can’t run CSS animations in Gmail – yet. I’ve also noticed that although the :before and :after pseudo class is supported, the “content” style is removed rendering the support pointless.

Takeaway

By leveraging attributes that Gmail does not strip (title or lang) and appending a universal selector to your styles, you can now create emails that are interactive and responsive in Gmail.

Does this mean we can stop inlining our CSS code? Sadly, no. The Gmail mobile apps and Gmail for Businesses still don’t support the <style> tag. So even though this is an interesting and promising development, the @Gmail #CanHasStyle campaign goes on!




Latest Comments
  1. Jaina

    The of cynic in me is waiting for this all to disappear in a mysterious Gmail update. I’m hopeful it won’t happen and we’ll get more of this sort of thing, not just in Gmail, but across the board!

    • Justin

      Hi Jaina,

      Yes, this does look like something they would remove once they get wind of it. But perhaps Google felt that class and ids might conflict with their Gmail “Labs” plugins so they removed it while lang and title might won’t . We’ll just have to wait and see but I agree the email clients need to start working towards some kind of common standards!

  2. Olof

    great post! since when is this possible in gmail?

    • Justin

      Well the Email on Acid guys discovered that Gmail allowed the <style> tag in the head in April so it could be as early as then if not earlier!

  3. Mpapous

    Hello mate,

    interesting post. I tried to use your tool and I received the email in my inbox but the hover wasn’t working. Any ideas why would this be?

    Check this link out

    http://konceptweb.co.uk/freshinbox.gif

    Thank you in advance

  4. Pepe Aguilar

    Hi.
    I did try but don´t work
    I do not understand where add :

    .img-swap:hover img,
    * [lang~="x-img-swap"]:hover img{
    max-height: 0px;
    height:0px;
    }

    I use thunderbird
    ¿may I change the code? ¿where?

    How add the code?

    Sorry for my English

    • Justin

      You can use the generator to email yourself an example. From there you can view the source to see how it works.

  5. sheikhabuzaffar

    It is working when your tool sends the hovering image but when we forward it to other persons it does not work…why is this happening…???

    • Justin

      Some clients make changes to the HTML when replying such as dropping the styles in the head and causes this technique not to work. If you can let me know the exact clients you’re using I could take a look into it.

  6. jay

    Doesn’t .divbox, make the background-color green even at normal state? I commented it out and it seems to work, Please confirm.

    /*.divbox,*/ * [lang~="x-divbox"]:hover {
    background-color: green !important;
    color: white;
    }

    Divbox Content

    • Justin

      Hi Jay, Thanks for the comment. I’m surprised you’re the first to chime in on that! It was a typo. Instead of “.divbox”, it should’ve been “.divbox:hover”. I’ve since updated the code.

  7. Eric E Zanke

    Do you have an example of a media query statement: “Gmail even allows media queries (@media) and keyframes (@keyframe). ” using the techniques /attributes you indicate in the article?

  8. Diego

    Hi everybody!

    I was testing this tools some weeks ago, and now i come back and nothing is working as used to. Gmail did some changes?

    Thanks!

  9. Sabrina Nettekoven

    Hi,

    great code, but when i change the text color in the non hover state then the hover effect color does not work anymore..

    Regards

  10. Cyrill Gross

    Unfortunately, the GMail update rolled out end of September 2016 terminated the support of css selectors.
    Check my blog about my learning from playing with the updated GMail preprocessor: http://www.mayoris.com/gmail-and-media-queries-developers-heaven-is-still-far-away/

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">