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

Media queries behave incorrectly at breakpoints at non-100% browser zoom on Firefox & Edge #19197

Closed
dxinteractive opened this issue Feb 15, 2016 · 10 comments

Comments

@dxinteractive
Copy link

So Bootstrap 3 has media queries using px values, and makes use of this kind of code to provide pixel boundaries to use in min or max screen size media queries:

$screen-sm-max: ($screen-md-min - 1) !default;

Unfortunately this leaves a slightly-less-than-one pixel wide gap if the browser ever uses decimal viewport widths to workout when rules inside media queries should be applied - depending on the browser this happens when a non-standard zoom is set (100%, 125% etc.).

Working example:
http://codepen.io/dxinteractive/pen/pgYJOm
No two divs should ever display at the same time.

Open Firefox or Edge and view that pen, zoom the browser to 110% or 125% if it isn't already, and resize the window to one of the breakpoints such as between 991px and 992px. All divs now show at once:
breakpoints

Chrome does not report decimal viewport widths even when zoomed, I assume it rounds the values when applying media queries.

While the problem can be avoided by only ever using either max or min media queries, much of Bootstrap's default css uses both (such as navbar, which suffers from this same problem).

I would also expect non-100% zoom levels on browsers are becoming more common as high DPI screens become more common. For example Firefox and Edge were both set to 125% zoom after fresh install on this PC.

But perhaps this is being addressed for Bootstrap 4? https://github.com/twbs/bootstrap/blob/v4-dev/scss/_variables.scss

@cvrebert
Copy link
Collaborator

We don't officially support non-pinch ("page") zooming; see http://getbootstrap.com/getting-started/#support-browser-zooming

I would also expect non-100% zoom levels on browsers are becoming more common as high DPI screens become more common.

I would expect them to perhaps use a different size for CSS pixels, like mobile devices do, but that's very different from page zooming, which breaks a ton of webpages.

For example Firefox and Edge were both set to 125% zoom after fresh install on this PC.

While that's not impossible, I find it highly unlikely. What OS are you running, and what are your monitor's resolution and DPI?

But perhaps this is being addressed for Bootstrap 4?

It's possible that our new responsive utilities scheme (http://v4-alpha.getbootstrap.com/layout/responsive-utilities/) might avoid the problem, but we haven't specifically tested or considered your issue.

@dxinteractive
Copy link
Author

Thanks, sorry I wasn't aware it was explicitly stated that this kind of thing isn't covered.

While that's not impossible, I find it highly unlikely. What OS are you running, and what are your monitor's resolution and DPI?

3 PCs at home, Windows 10, 10 and 7, all 1920x1080, 166ppi, 127ppi and 127ppi respectively.

Yeah it seems like it should be unlikely, but on every PC I have to test on right now, they fail this test because they all have non-100% zoom levels by default (Ctrl+0). To me it doesn't appear that these are due to a higher number of screen pixels vs document pixels like retina displays do, but I'm not completely sure how desktop browsers handle that. IE and Edge explicitly state a 125% default zoom level, Firefox just appears at a 125% size, and all appear to fail that pen when you resize the browser just right.

It seems that for many people IE9+, Edge and Firefox all inherit the default Windows zoom value when they work out the default zoom size for the browser. Windows 7 / 8 / 10 has a default OS level view size of 125% on 1920x1080 screens. IE and Edge display all websites as a "125% zoom" and assign the Ctrl+0 shortcut to that zoom level. Firefox says it is at "100% zoom" and assigns it the Ctrl+0 shortcut, even though it's clearly displaying at 125%. Here's a thread discussing that from a couple of years ago with a better explanation than I can give: http://superuser.com/questions/804949/why-does-firefox-interpret-100-zoom-differently-to-other-browser

I don't entirely expect this is something that can be fixed or should be fixed as part of Bootstrap, but I'd be very interested if anyone else experiences the same issues. The actual impact of the bug is tiny, you only see it if you happen to resize your window to the exact size (4 possible pixel browser widths out of 1800+), but it's very reproducible.

@patrickhlauke
Copy link
Member

Re-checking this more thoroughly, it does actually seem that high-dpi on Windows does a combination of things. You can set what is effectively something that's not quite a device pixel ratio (as the actual resolution that the display is set is still the same) but a general scaling factor for text/apps/items. This value is then used in IE/Edge to label its "default" zoom level. Very strange. In the context of the browser and how it displays things, however, it's effectively then doing the same as mobile devices and their use of viewport/dpr, so in terms of behavior of web content, this shouldn't make an actual difference. In principle, I agree though that it's worth ensuring/checking that stuff works in some of these scenarios.

@cvrebert
Copy link
Collaborator

So with regard to page zooming, I think the theoretically proper fix would be to use the "strictly less than" syntax from Media Queries Level 4, i.e. @media (width < 768px) instead of @media (max-width: 767px), thus avoiding the 1px of limbo, but there doesn't seem to be caniuse data for this, plus MQ4 is pretty new, so this option almost certainly lacks sufficient browser support to be viable. And it hasn't even been successfully polyfilled yet with respect to fractional pixels (postcss/postcss-media-minmax#12).

With that out of the way, the next best thing I can come up with would be to subtract something like 1e-12px (instead of 1px) when calculating the bound for max-width media queries. (Really it should be something like Ruby's Float#prev_float, but Sass doesn't offer such a function.) Increasing the Sass precision setting would also be needed if we wanted to absolutely maximize the extent of the fix, but I question whether it'd be worth it for such a niche and not-officially-supported use-case.

@patrickhlauke
Copy link
Member

I question whether it'd be worth it for such a niche and not-officially-supported use-case.

indeed, the core problem (that using min-width or max-width intrinsically leaves the actual value min/max value itself in limbo) is intrinsic to media queries at the moment. the pain of trying to work around it isn't justified (most other sites using media queries are likely to have the exact same issue currently)

@cvrebert
Copy link
Collaborator

@mdo Shall we deem this WontFix?

@dxinteractive
Copy link
Author

Didn't realise this problem ran so deep. Understood if you go with Wontfix.

With that out of the way, the next best thing I can come up with would be to subtract something like 1e-12px (instead of 1px) when calculating the bound for max-width media queries. (Really it should be something like Ruby's Float#prev_float, but Sass doesn't offer such a function.)

You might not need watertight float precision to just fix the symptoms. Subtracting 0.001px instead of 1px to get your max widths fixes the issue for me on Edge and Firefox (IE not tested). Not perfect, but there is only a total of 3px of possible browser widths where this issues shows up, and reducing it to 0.001px per breakpoint minimises chances of seeing the bug pretty well. I haven't been able to find any details on older browser support for decimals in px values in media queries though, and if an older browser were to reject an entire media query based on the fact that it wasn't set up to parse or process decimals then that'd be a big problem.

most other sites using media queries are likely to have the exact same issue currently

Can confirm that some sites using Susy grids have the same problem.

@mdo
Copy link
Member

mdo commented Feb 17, 2016

Yeah, probably not something we want to dive into right now. Honestly feel like browsers need to get way better at handling these page zoom oddities—super frustrating to see different math and rounding errors impede perfectly valid code.

@Salubritas
Copy link

Salubritas commented Aug 3, 2019

I see this problem in Chrome, Firefox and Edge without any browser zoom. That's using the CodePen example URL given in the first post, with width at 991px. All the divs appear at once, on all those browsers.

I use Windows display scaling of 125% which I assume is what is causing the browsers to pass fractional widths to the media queries.

@twbs twbs locked and limited conversation to collaborators Aug 3, 2019
@mdo
Copy link
Member

mdo commented Aug 3, 2019

This is a four year old issue that we’ve addressed as best we can in v4 with fractional media queries.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants