Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 221
vijay tyagi Avatar asked May 18 '17 09:05

vijay tyagi


People also ask

Why media queries not working?

Media Query Not Working on Mobile Devices If media queries work on desktop and not on mobile devices, then you most likely haven't set the viewport and default zoom. Note: You only need to add one of the code lines above, and usually, the first one does the job.

What is @media min width?

The min-width and max-width are media features that correspond to a certain media type that has been specified in the media query. The min-width specifies the minimum screen width of a specific device, meanwhile, The max-width media feature states the maximum screen width of a specific device.


1 Answers

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;
  }
}
like image 159
Frits Avatar answered Nov 17 '22 14:11

Frits