How Yahoo! Mail’s Mangling of Media Queries Affects Your CSS
Update: It looks like Yahoo! Mail fixed this issue, so the advice in this post is no longer relevant! :)
The first part of this article talked about what you should be aware when creating email with Media Queries in relation to Yahoo! Mail.
In this article we’ll look at what happens when Yahoo! Mail mangles media queries. This article will be very technical in nature and may be of limited value if you’re just looking for tips. However, if you want to understand what appears to be going on “under the hood”, read on!
Take the following code sample:
<style> .div1, .div2, .div3 { border: 1px solid black; color: #dddddd; width: 30px; padding: 10px; margin: 10px; float: left; } @media only screen and (max-device-width: 480px) { .random-rule { height:50px; } .div3 { background-color: green; } } .div1 { background-color: blue; } .div2 { background-color: red; } </style> <div class="div1">div1</div> <div class="div2">div2</div> <div class="div3">div3</div>
When you load the above code in a regular web (non-mobile) browser, you’ll see three boxes:
The left box will be blue, the middle box will be red and the right box will be white (The media query will prevent the CSS rule that sets the third box green).
However if the code was sent to an email and rendered in the regular web version of Yahoo! Mail, you’d see:
Here Yahoo! Mail did two things that messed up the CSS as you intended.
1) It “activated” the CSS rule within the media query that was only intended to be visible on mobile devices (green box).
2) The first CSS rule after the media query was not activated (blue box)
Analysis of the Modified Media Query
Lets take a look at what Yahoo! Mail did to our CSS.
<style> #yiv7320523903 .yiv7320523903div1, #yiv7320523903 .yiv7320523903div2, #yiv7320523903 .yiv7320523903div3 { border:1px solid black;color:#dddddd;width:30px;padding:10px;margin:10px;float:left; } _filtered #yiv7320523903 { } #yiv7320523903 .yiv7320523903div3 { background-color:green; } #yiv7320523903 #yiv7320523903 .yiv7320523903div1 { background-color:blue; } #yiv7320523903 .yiv7320523903div2 { background-color:red; } </style> <div class="yiv7320523903div1">div1</div> <div class="yiv7320523903div2">div2</div> <div class="yiv7320523903div3">div3</div>
We can tell Yahoo! Mail did the following things:
1) It embedded the email in a div with the id #yiv7320523903 (not shown in the above markup and appears to be randomly generated).
2) It prepended the container div id to our CSS rules.
3) It modified the names of our CSS classes by prepending the id to it (from .div1 to .yiv7320523903div1).
So far so good. This shouldn’t affect our CSS one bit!
The Bad News
Now the following changes mess up our intended CSS rules.
It converted our media query from:
@media only screen and (max-device-width: 480px) { .random-rule { height:50px; } .div3 { background-color: green; } }
to
_filtered #yiv7320523903 { } #yiv7320523903 .yiv7320523903div3 { background-color:green; } #yiv7320523903
This has the following effect:
1) The media query was replaced with a _filtered rule which as far as I know is an unsupported rule.
2) It moved the rule that set the third box green within the media query outside the _filtered block, effectively activating it since its no longer subject to a media query filter.
3) It added an incomplete rule at the bottom that just starts with #yiv7320523903
The incomplete rule at the bottom will be interpreted by the browser as part of the first rule originally outside the media query block as:
#yiv7320523903 #yiv7320523903 .yiv7320523903div1 { background-color:blue; }
Causing it to mangle the rule that sets the first box to blue.
The Fix
Applying the techniques discussed in the previous post we change our markup to:
... @media only screen and (max-device-width: 480px) { .random-rule { height:50px; } .div3[class=div3] { background-color: green; } } .yfix{} .div1 { background-color:blue; } ...
Which then produces:
_filtered #yiv0279000434 { } #yiv0279000434 .yiv0279000434div3 .filtered99999 { background-color:green; } #yiv0279000434 #yiv0279000434 .yiv0279000434yfix{} #yiv0279000434 .yiv0279000434div1 { background-color:blue; }
The modification of the media query now produces an invalid CSS for the rule that sets the 3rd box to green so it’s not active.
The .yfix{} bogus rule right after the media query block also neutralizes the incomplete CSS rule that is produced after a media query block.
With the updated changes our email now displays as intended.
The Key Take Away
Until Yahoo! Mail fixes their CSS transformer code, remember these two rules when sending to recipients at Yahoo!:
1) Craft your media query CSS rules to avoid them being enabled in Yahoo! Mail using this technique.
2) Avoid putting regular CSS beneath your Media Query block or use the .yfix{} trick mentioned above.
Update:
Having comments in your CSS tags also causes the first CSS rule beneath a comment to be “mangled” as well. However most mailers strip comments before an email is sent so this is less likely to be a problem.