vijay tyagi
vijay tyagi

Reputation: 2256

Safari: Media query not firing at the expected width

I have written a CSS media query like this -

@media screen and (max-width: 59.9375em) {
  .left {
   display: none;
  }
}

This works fine across all the browsers except Safari 10.0.4 and below. Safari seems to be handling the media queries differently.

Other browsers seem to be taking the window.innerWidth as viewport width for triggering media queries, but safari seems to be taking document.documentElement.clientWidth as viewport width and triggers the media queries accordingly.

I can see a difference of 15px between the actual and expected breakpoint. I am looking for a cross-browser way for dealing with this issue. Thoughts are welcome, thanks in advance.

Upvotes: 14

Views: 8311

Answers (5)

Frits
Frits

Reputation: 7624

The window width vs actual width is actually a super interesting topic. Snuggug has a really extensive explanation for it, but in short it's based on how the scroll bars are placed in different browsers.

Some browsers overlay the scroll bar on top of the content/site. Other browsers shorten the width of the content/site and have the scroll bar next to it. This obviously creates some discrepancies in how different browsers calculate the width of the viewport.

A potential problem is your usage of em as a unit of measurement.

It is important to remember that em is a measurement unit based on your current font size, and is therefore open to browser interpretation.

Depending on your font-family and overall font-size, 60em is usually around the area of 800px. Which means your query would be more specific looking like this:

@media screen and (max-width: 800px) {
  .left {
     display: none;
  }
}

If you are unsure about the styling being overridden, you can always apply an important rule like this:

@media screen and (max-width: 800px) {
  .left {
     display: none !important;
  }
}

If you would prefer to not use the !important tag in your CSS, then you will need to ensure that you look out for the two scenarios listed below:


CSS reads from Top to Bottom

This means that if you have a rule specified for your .left element, it needs to be placed before your media query and not after

The WRONG layout would look like this:

@media screen and (max-width: 800px) { //media query BEFORE rule
  .left {
     display: none;
  }
}

.left {
   .display:block;
}

The CORRECT layout would look like this:

.left {
   .display:block;
}

@media screen and (max-width: 800px) { //media query AFTER rule
  .left {
     display: none;
  }
}

The next bit to keep in mind is:


Nested CSS selectors take precedence

Use the same amount of parent selectors (or more) in your media query rule.

The WRONG series of selectors:

.container .left { //2 selectors used in query
   .display:block;
}

@media screen and (max-width: 800px) {
  .left { //only 1 selector used in query therefore overwritten by the previous rule - this should have atleast 2 selectors to overwrite the previous rule
     display: none;
  }
}

The CORRECT series of selectors:

.container .left { //2 selectors used in query
   .display:block;
}

@media screen and (max-width: 800px) {
  body .container .left { //3 selectors used in query
     display: none;
  }
}

Upvotes: 9

trusktr
trusktr

Reputation: 45504

You should read these two articles:

Then you'll understand why you have the problem you've asked about.

TLDR: em values are based on root font-size values, but in the case of Safari vs other browsers, em is either relative to the initial value or the root value (browsers pick one or the other for media queries, but not both, which can cause discrepancies across browsers)

Upvotes: 0

try this css hack :

@media screen and (min-color-index:0) and(-webkit-min-device-pixel-ratio:0) { 
@media {
  .left { 
      display: none;
  }
}}

Source : https://jeffclayton.wordpress.com/2015/04/28/css-hacks-for-safari-6-1-7-and-8-not-chrome/

Upvotes: 2

Kumar Rahul
Kumar Rahul

Reputation: 79

you have to use media query after .left class as per the css rule

For example

.left {
  display:inline;
}

@media screen and (max-width: 59.9375em) {
  .left {
   display: none !important; //important will override all the .left class.
  }
}

Upvotes: -1

foobar
foobar

Reputation: 619

use px (pixels) instead of em. em is not fixed but it is relative. parsed different for different browsers.

@media screen and (max-width: 59.9375px) {
  .left {
   display: none;
  }
}

Upvotes: 1

Related Questions