foundation / foundation-emails

Quickly create responsive HTML emails that work on any device and client. Even Outlook.
https://get.foundation/emails/docs/
MIT License
7.77k stars 1.09k forks source link

Media queries fail after inlining #399

Open jasonlmann opened 8 years ago

jasonlmann commented 8 years ago

How can we reproduce this bug? I have two different font-size values in my app.scss file. I used the media query exactly as shown in the docs:

/* Main header */
.header {
    h1, .tagline {
        font-family: Palatino, "Times New Roman", serif;
        margin-bottom: 0;
        color: $black;
    }
    h1 {
        font-weight: bold;
        font-size: 48px;
        line-height: 48px;
        text-transform: uppercase;

        @media only screen and (max-width: #{$global-breakpoint}) {
            font-size: 20px;
            line-height: 20px;
        }
    }

    .tagline {
        font-size: 14px;
        line-height: 14px;
        }
    }
}

When I run npm start, I see the header resize for a smaller viewport:

Wide version:

screenshot 2016-04-28 10 30 15

iPhone 5:

screenshot 2016-04-28 10 30 37

However, when I run npm run build (or npm run zip or npm run litmus), the header does not resize:

screenshot 2016-04-28 10 32 33

When I inspect the h1 in Chrome, I see that the media query styles have not been applied to the tag by the inliner: Post inlined h1 tag:

screenshot 2016-04-28 10 33 45

Web Inspector in Chrome:

screenshot 2016-04-28 10 33 55

This appears to be true in every mobile client in Litmus as well.

Is it possible that the inliner is not working correctly? I don't totally understand how it's supposed to work. Help!

rafibomb commented 8 years ago

While media queries cannot be inlined, they should override the default styles inside the breakpoint. Are you seeing the media query inside the body tag of you email?

jasonlmann commented 8 years ago

Thanks, @rafibomb. I added !important to the font-size and line-height declaration and that fixed it.

Here's my (working) code for that header:

/* Main header */
.header {
    h1, .tagline {
        font-family: "Palatino", "Times New Roman", serif;
        margin-bottom: 0;
        color: $black;
    }
    h1 {
        font-weight: bold;
        font-size: 48px;
        line-height: 48px;
        text-transform: uppercase;

        @media only screen and (max-width: #{$global-breakpoint}) {
            font-size: 24px !important;
            line-height: 24px !important;
        }
    }

    .tagline {
        font-size: 14px;
        line-height: 14px;
        }
}

I'm not sure if that's always necessary. If so, maybe the inliner can add it automatically? Or maybe I should just know better...

rafibomb commented 8 years ago

Let's put it this way - using a CSS inliner should not change the look of your email. So needing important statements on inlined code is odd. If you can determine what's casing the specificity issue that would really help. Looking at where the media queries are moved after inlining might tell the story.

jasonlmann commented 8 years ago

I'll take a look, Rafi. Thanks.

jasonsubers commented 8 years ago

Just chiming in here; I have experienced the same behavior with my SASS media queries failing after inlining. As suggested here, using the !important tag on my mobile styles resolved the issue.

roopemerikukka commented 8 years ago

Same problem in here. Element inline styles override the media query rules (at least in Chrome).

3zzy commented 8 years ago

Same problem for me as well.

matthewmcclatchie commented 8 years ago

I'm seeing the same problem and using !important on my styles resolves the issue, using Chrome to view.

callaginn commented 7 years ago

I'm also having this issue, even when using the !important override. I should also note that I'm using the "npm run build" command in terminal and it's not inserting any media queries into the code at all.

The page renders the responsive styles perfectly if I run the build without inlining. But that's not gonna work on all these crappy email clients.

Any ideas anyone?

dargouder commented 7 years ago

I am also having this issue and !important resolved it - at the moment using Chrome to view it.

davidpatters0n commented 7 years ago

Also experiencing the same issue in Chrome. Found that using the !important issue solved it too. However this should totally not be necessary. On the topic of using important! with media queries. I'm now facing a conundrum of an issue whereby I'd like to display two different styles different screen sizes. Now given:

.product-card-row
  @media (min-width: 480px)
    display: none !important

  @media (min-width: 768px)
    display: table !important

The above will never work correctly because if the screen size is bigger than 480!px display will always be table since it last media instance.

As mentioned you shouldn't have to use !important, these rules should be respected regardless. What is the correct way of handling multiple media queries without having to use important.

@rafibomb - Do you know if there is any movement on this issue?

nikitasol commented 7 years ago

Just to add, the media queries are added as expected correctly between style tags after the major media queries definitions like table.body, table.menu, etc. in the head of the file. All these definitions carry !important styles which is correct and obligatory for the media queries at this point as inlining will always override stripped style. If you revise code made by other major email campaign tools you will notice that all of them use the media queries with !important which is expected.

nikitasol commented 7 years ago

If you have doubts, you can always check css specifity articles. Like this one: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity

Inline styles added to an element (e.g., style="font-weight:bold") always overwrite any styles in external stylesheets, and thus can be thought of as having the highest specificity.

timohausmann commented 7 years ago

If you are missing the media queries in <head> after running inliner, make sure the placeholder <!-- <style> --> is still there - it will be replaced with the media query styles.

zsoltmar commented 6 years ago

I so wish what @timohausmann told would be in the documentation. Would've saved me some time figuring out what is happening with my media queries.

billyromano commented 4 years ago

In order to use media queries in emails you need to include the !important flag as part of the property declaration. However, it's only necessary for styles that are inlined.

Inlined styles take precedence over style/media query tags and you need to override inlined styles for your code to work. It's a basic order of operations for email developers.

A lot of web designers rail against the overuse of the !important declaration but, for email designers, it’s our best friend. - Jason Rodriguez @Litmus

@rafibomb please include this in your Zurb Email Template Docs when using media queries. Also, this issue can be closed. Thanks!