{"id":829,"date":"2014-08-13T09:00:52","date_gmt":"2014-08-13T09:00:52","guid":{"rendered":"http:\/\/freshinbox.com\/blog\/?p=829"},"modified":"2016-10-19T02:43:35","modified_gmt":"2016-10-19T02:43:35","slug":"interactive-emails-in-gmail-using-css-attribute-selectors","status":"publish","type":"post","link":"https:\/\/freshinbox.com\/blog\/interactive-emails-in-gmail-using-css-attribute-selectors\/","title":{"rendered":"Make your email interactive in Gmail by using CSS attribute selectors"},"content":{"rendered":"<p><I><B>Update Oct 2016:<\/B> With the new responsive email update, this technique no longer works in Gmail. It was a good run.<\/I><BR><BR><\/p>\n<p>A few days back I posted the article <a href=\"https:\/\/freshinbox.com\/blog\/gmail-supports-style-sort-of\/\">Gmail Supports the Style tag!&#8230; Well sort of<\/a> 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.<\/p>\n<p>In this article I&#8217;ll delve into the nitty gritty of what I\u2019ve found concerning this technique.<\/p>\n<div style=\"max-width:400px;margin:20px auto;padding:10px;border:2px solid #AC88AC;text-align:center;border-radius:3px;\">\nCan&#8217;t wait to see interactive email in Gmail?<br \/>\n<a href=\"https:\/\/freshinbox.com\/resources\/tools\/carousel\/\">Try out the Image Carousel for Email Tool<\/a>.\n<\/div>\n<p>Below is the code of the <a href=\"https:\/\/freshinbox.com\/blog\/gmail-supports-style-sort-of\/\">previous article<\/a> showing a hoverable box. I also added a pair of class selectors (.divbox) and attributes (class=&#8221;divbox&#8221;) 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 <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTML\/Global_attributes\" target=\"_blank\">attributes<\/a> as well as <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/Attribute_selectors\" target=\"_blank\">attribute selectors<\/a>.<\/p>\n<pre class=\"lang:text decode:true \" >&lt;html&gt;\r\n&lt;head&gt;\r\n&lt;style&gt;\r\n.divbox:hover,\r\n* [lang~=\"x-divbox\"]:hover{\r\n  background-color: green !important;\r\n  color: white;\r\n}\r\n&lt;\/style&gt;\r\n&lt;\/head&gt;\r\n&lt;body&gt;\r\n&lt;div class=\"divbox\" lang=\"x-divbox\" style=\"padding:10px;width:100px;height:40px;\r\nbackground-color:#eeeeee;\"&gt;Divbox Content&lt;\/div&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p><BR><br \/>\n<img decoding=\"async\" src=\"https:\/\/freshinbox.com\/blog\/wp-content\/uploads\/2014\/08\/gmail-hover.gif\" alt=\"gmail-hover\" width=\"450\" class=\"aligncenter\" \/><BR><BR><\/p>\n<p>With a combination of class and attribute selectors, we\u2019re now able to create interactive email content for all major email clients except for the lone holdout &#8211; Outlook 2007\/2010\/2013!<\/p>\n<p>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.<\/p>\n<p>Here\u2019s a summary of how Gmail processes CSS in a style tag (in the &lt;head&gt; of the email).<\/p>\n<pre class=\"lang:css decode:true \" >\r\n\r\n.divbox {..}  \/\/Allowed but pointless - Gmail strips class attributes from elements\r\n#divbox {..}  \/\/Allowed but pointless - Gmail strips id attributes from elements\r\n\r\n[class~=\"divbox\"] {...} \/\/Removed by Gmail\r\n* [class~=\"divbox\"] {...} \/\/Allowed but pointless - No class attributes\r\n\r\ndiv {...} \/\/Allowed but too generic to be useful\r\ndiv:hover {...} \/\/Removed by gmail. No pseudo class support? Not so fast!\r\n* div:hover {...} \/\/Allowed! Interesting\u2026\r\n\r\n* [lang~=\"x-divbox\"] {...} \/\/Allowed! Now we\u2019re talking\r\n\r\n* [lang~=\"x-divbox\"]:hover {...} \/\/Allowed! Magic! :)\r\n\r\n<\/pre>\n<p><BR><\/p>\n<p>A word of warning. <a href=\"http:\/\/emails.hteumeuleu.fr\" target=\"_blank\">R\u00e9mi Parmentier<\/a> noticed that having nested @ declarations (ie, a @font-face or @import declaration within a @media query) might cause Gmail to toss out the whole &lt;style&gt; block and <a href=\"http:\/\/emailcodegeek.com\">Mark Robbins<\/a> 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 &lt;style&gt; block at the top of your CSS declarations.<BR><BR><\/p>\n<p><b>Try it for yourself<\/b> <\/p>\n<p>I\u2019ve updated the <a href=\"https:\/\/freshinbox.com\/tools\/rollover\/\">Rollover Image Tool<\/a> to support Gmail. Go ahead and <a href=\"https:\/\/freshinbox.com\/tools\/rollover\/\">create your own rollover images for email<\/a>!<\/p>\n<p><a href=\"https:\/\/freshinbox.com\/tools\/rollover\/\"><img decoding=\"async\" src=\"https:\/\/freshinbox.com\/blog\/wp-content\/uploads\/2014\/08\/gmail-rollover.gif\" alt=\"gmail-rollover\" width=\"450\" class=\"aligncenter size-full\" \/><\/a><BR><\/p>\n<p><strong>Why use the lang attribute?<\/strong><br \/>\n<i>(see update for why I now prefer the <code>summary<\/code> attribute).<\/i><\/p>\n<p>Gmail strips class and id attributes from all elements but leaves some other attributes intact: <code>style, title, lang, width, height, alt, href<\/code>.<\/p>\n<p>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 &#8211; however title comes with one side-effect &#8211; when the user hovers the cursor over the element, the title would be visible.<\/p>\n<p>I chose the lang attribute because it is a universal attribute (valid for all elements) that is not visible when hovered over. Naturally we\u2019re not using this attribute for its intended purpose &#8211; but there\u2019s a technical exception in the HTML specifications that allow us to use it this way. By pre-pending the attribute value with an &#8220;x-&#8220;, 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.<\/p>\n<p><b>Update:<\/b> Eric Lepetit (<a href=\"https:\/\/twitter.com\/ericlepetitsf\">@ericlepetitsf<\/a>) found other attributes that can be used as well &#8211; <i>char<\/i> and <i>summary<\/i> &#8211; I like summary since its pretty unencumbered. <a href=\"http:\/\/emails.hteumeuleu.fr\" target=\"_blank\">R\u00e9mi Parmentier<\/a> prefers the <i>aria-labelledby<\/i> attribute . In addition, R\u00e9mi discovered a way to only exclusively target Gmail webmail by <a href=\"https:\/\/litmus.com\/community\/discussions\/1275-gmail-app-gmail-webmail-and-inbox-metrics\" target=\"_blank\">testing for the Google proxy image<\/a>.<BR><BR><\/p>\n<p><strong>Breakdown<\/strong><\/p>\n<p>Here\u2019s a total breakdown of all the styles I\u2019ve tried and found working in Gmail:<\/p>\n<ul>\nThe following works in Gmail:<br \/>\n* E[foo]<br \/>\n* E[foo=&#8221;bar&#8221;]<br \/>\n* E[foo~=&#8221;bar&#8221;]<br \/>\n* E[foo^=&#8221;bar&#8221;]<br \/>\n* E[foo*=&#8221;bar&#8221;]<br \/>\n* E[foo$=&#8221;bar&#8221;]<br \/>\n* E:hover<br \/>\n* E:link<br \/>\n* E:visited<br \/>\n* E:active<\/p>\n<p>E F<br \/>\nE > F<br \/>\nE + F<br \/>\nE ~ F\n<\/ul>\n<p>Gmail even allows <a href=\"http:\/\/emailcodegeek.com\/responsive-email-in-gmail\/\">media queries<\/a> (@media) and keyframes (@keyframe). Unfortunately, Gmail strips all animation related styles and thus, we can\u2019t run CSS animations in Gmail &#8211; yet. I\u2019ve also noticed that although the :before and :after pseudo class is supported, the \u201ccontent\u201d style is removed rendering the support pointless.<\/p>\n<p><strong>Takeaway<\/strong><\/p>\n<p>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. <\/p>\n<p>Does this mean we can stop inlining our CSS code? Sadly, no. The Gmail mobile apps and <a href=\"https:\/\/www.campaignmonitor.com\/blog\/post\/4219\/gmail-and-google-apps-css-support-and-rendering-differences\">Gmail for Businesses<\/a> still don\u2019t support the &lt;style&gt; tag.  So even though this is an interesting and promising development, the <a href=\"https:\/\/freshinbox.com\/blog\/gmail-can-has-style\/\">@Gmail #CanHasStyle<\/a> campaign goes on!<\/p>\n<p><BR><BR><br \/>\n<div style=\"padding:10px; border: 2px solid #99C731;background-color:#FFF8DC;border-radius:5px;\">\n<form action=\"https:\/\/freshinbox1.createsend.com\/t\/i\/s\/adrmi\/\" method=\"post\" id=\"subForm\">\n<span class=\"fisub_header\" style=\"font-weight:bold;\">Subscribe to the #EmailGeeks Newsletter<\/span>\n<p><input id=\"fieldEmail\" name=\"cm-adrmi-adrmi\" type=\"email\" style=\"width:90%\" required placeholder=\"Your Email Address\" \/><\/p>\n<p><button type=\"submit\">Subscribe<\/button><\/p>\n<\/form>\n<\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few days back I posted the article <a href=\"http:\/\/freshinbox.com\/blog\/gmail-supports-style-sort-of\/\">Gmail Supports the Style tag!&#8230; Well sort of<\/a> 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.<BR><BR><\/p>\n<p>In this article I&#8217;ll delve into the nitty gritty of what I\u2019ve found concerning this technique&#8230;<\/p>\n","protected":false},"author":2,"featured_media":821,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[23,28,24,25],"tags":[],"_links":{"self":[{"href":"https:\/\/freshinbox.com\/blog\/wp-json\/wp\/v2\/posts\/829"}],"collection":[{"href":"https:\/\/freshinbox.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/freshinbox.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/freshinbox.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/freshinbox.com\/blog\/wp-json\/wp\/v2\/comments?post=829"}],"version-history":[{"count":70,"href":"https:\/\/freshinbox.com\/blog\/wp-json\/wp\/v2\/posts\/829\/revisions"}],"predecessor-version":[{"id":3247,"href":"https:\/\/freshinbox.com\/blog\/wp-json\/wp\/v2\/posts\/829\/revisions\/3247"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/freshinbox.com\/blog\/wp-json\/wp\/v2\/media\/821"}],"wp:attachment":[{"href":"https:\/\/freshinbox.com\/blog\/wp-json\/wp\/v2\/media?parent=829"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/freshinbox.com\/blog\/wp-json\/wp\/v2\/categories?post=829"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/freshinbox.com\/blog\/wp-json\/wp\/v2\/tags?post=829"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}