Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gmail removes <style> tags that contain certain @ declaration within an @ declaration #21

Open
hteumeuleu opened this issue Sep 23, 2016 · 11 comments
Labels
Gmail Webmail, iOS and Android apps

Comments

@hteumeuleu
Copy link
Owner

The mainstream desktop webmail of Gmail removes <style> tags that contain an @ declaration within an @ declaration.

The following code…

<html>
<head>
    <style>
        p { background:#e4505d !important; }
    </style>
    <style>
        p { background:#3cbc67 !important; }
        @media only screen and (max-width:320px) {
            @viewport { width:320px; }
        }
    </style>
    <style>
        p { background:#3cbc67 !important; }
        @ { @ }
    </style>
</head>
<body>
    <p style="color:#fff; background:#000;">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit.
    </p>
</body>
</html>

…is transformed by Gmail into the following :

<html>
<head>
    <style>
        p { background:#e4505d !important; }
    </style>
</head>
<body>
    <p style="color:#fff; background:#000;">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit.
    </p>
</body>
</html>
@hteumeuleu
Copy link
Owner Author

This bug is still present after the 2016 update.

@jamesmacwhite
Copy link

@hteumeuleu

Hi. I was unaware of this behaviour! To confirm, would something like this trigger the described behaviour:

@media screen { 
    @font-face { 
        /* Some font stuff */
    }
}

Is the only solution to split out CSS styling into separate <style> blocks?

@revelt
Copy link

@jamesmacwhite the issue needs clarification, as it is not enough to have two ampersands within a style tag to cause Gmail to strip it. For example, this class will set the text to red. In the following example, Gmail ripped out the @font-face, but kept another @media which colors text red:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en">
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
  <title>Checking</title>
  <style type="text/css">
  @media screen {
    @font-face {
      font-family: 'Roboto';
      src: url('http://secret-url/host/img/roboto-regular.ttf');
    }
  }
  @media screen {
    .red {
      color: red !important;
    }
  }
  </style>
</head>
<body>
  <table width="100%" border="0" cellpadding="0" cellspacing="0">
  <tr>
    <td class="red" style="font-family: Roboto, serif;">
      Text
    </td>
  </tr>
</table>
</body>
</html>

PS, I removed the domain of the hosted TTF for security purposes, but rest of the code is intact. Here's the screenshot of the test email proof in Gmail:

gmail_test

If Gmail really stripped the whole style tag, the above text would be in black.

@jamesmacwhite
Copy link

@revelt Thanks for the further testing!

There is a crucial difference in your test vs the original from @hteumeuleu, not sure if it makes a difference or not though.

You put .red CSS class in another media query, @hteumeuleu used a general selector. I wonder what happens if the .red class sat in the same <style> block but outside any form of media query. I'm thinking perhaps it would be removed.

@hteumeuleu
Copy link
Owner Author

Hi you two. Very interesting. From @revelt's test, here are the styles Gmail keeps:

@media screen{}
@media screen{div.m159bc71832e5f85a .m_4170545781705170558red{color:red!important}}

My initial test still produces the same result. So there seems to be something special going on with @font-face that strips it safely. I was under the impression that this previously had the same behavior that I reported here.

@revelt
Copy link

From my past experience with Gmail, if it finds any selectors that are not on the "supported" list, it will simply discard all the styles in head. I had this happening before when I used -webkit-max-device-pixel-ratio in the media queries to target all webkit (and that way, indirectly, CSS3 capabilities). That line alone was enough to cause gmail to discard all styles.

I see the original test uses @ { @ }, that looks suspicious to me. That would be the next on my test list - isolate and prove it doesn't cause trouble.

@revelt
Copy link

Also, @viewport in @viewport { width:320px; } is not among supported properties. If it's true, all <style> tags will be stripped from <head>.

@bharathibh
Copy link

bharathibh commented Mar 15, 2017

Gmail is also restricts media queries by location and by product not only the mentioned supported properties.
It says only Unsupported properties (by Gmail) will be ignored.
Reference

You can style email sent to Gmail using inline <style> blocks and standard CSS. Most CSS selectors, attributes, and media-queries are supported. Unsupported CSS properties and selectors may be ignored by Gmail.

But those Unsupported properties varies with location
@revelt in your case @viewport is supported at your location ,that why the <style> block is not removed.
Also see the detailed list of rolled out clients here

@jkupczak
Copy link

jkupczak commented Mar 13, 2018

Should this be revisited? Perhaps rewrite the title and explanation to be more accurate. For example, @media within @media works just fine for me. Based on @revelt and @bharathibh research from last year, it looks like it's specifically the unsupported properties like @viewport that are causing the problem.

@hteumeuleu
Copy link
Owner Author

hteumeuleu commented Mar 15, 2018

@jkupczak Interesting. I clearly remember that nested media queries didn't work. I just tested with the following code and it does indeed work.

<html>
<head>
    <style>
        p { background:#3cbc67 !important; }
        @media only screen and (max-width:320px) {
            @media only screen and (max-width:320px) {
                p { background:#3cbc67 !important; }
            }
        }
    </style>
</head>
<body>
    <p style="color:#fff; background:#000;">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit.
    </p>
</body>
</html>

@hteumeuleu
Copy link
Owner Author

@jkupczak So, it turns out Gmail does support nested media queries. But only if those are fully declared media queries. So the above example works. But @media { @media { … } } wouldn't work. The following example:

<style>
    h1 { background:#3cbc67 !important; }
    @media only screen and (max-width:320px) {
       @media {
          h1 { background:#3cbc67 !important; }
       }
    }
</style>

…is transformed by Gmail into the following:

<style>
    h1 { background:#3cbc67 !important; }
</style>

What's interesting is that this falls more to a classic case of styles filtering, where only the @media declaration is filtered, but not the rest of the <style> tag. Still, the original issue is still there in Gmail as of today. But I'll adjust the title to reflect that this only concerns certain @ in a @ declaration, and not all nested @media media queries.

@hteumeuleu hteumeuleu changed the title Gmail removes <style> tags that contain an @ declaration within an @ declaration Gmail removes <style> tags that contain certain @ declaration within an @ declaration Mar 15, 2018
@hteumeuleu hteumeuleu added Gmail Webmail, iOS and Android apps and removed bug labels Jul 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Gmail Webmail, iOS and Android apps
Projects
None yet
Development

No branches or pull requests

5 participants