window.matchMedia fails on 125% DPI on Windows
Reported by
yeldi...@gmail.com,
Nov 22 2016
|
||||||||||
Issue description
Chrome Version : 54.0.2840.99 (Official Build) m (64-bit)
OS: Windows 7, 10
URLs (if applicable) :
Other browsers tested:
Add OK or FAIL, along with the version, after other browsers where you
have tested this issue:
Safari:
Firefox: OK
IE:
What steps will reproduce the problem?
(1) Set DPI to 125% in Windows settings
(2) Open any page at 989px screen width
(3) Run code
3.1 window.matchMedia('(min-width: 720px) and (max-width: 989px)')
3.2 window.matchMedia('(min-width: 990px) and (max-width: 1277px)')
What is the expected result?
3.1 will return object with property matches: true
What happens instead?
3.1 and 3.2 both return matches: false
Please provide any additional information below. Attach a screenshot if
possible.
,
Nov 22 2016
,
Nov 22 2016
,
Nov 23 2016
Reproduces at 150% too, at width 989px, though it's kinda tricky to actually resize the window at that dsf. oshima: My hunch is that this is use-zoom-for-dsf related. Since we're scaling the viewport now it probably ends up with a non-integer size when it's compared to the matchMedia call. Does this reproduce on ChromeOS?
,
Nov 28 2016
Don't know about ChromeOS but works as expected on Linux (Chromium 54.0.2840.100)
,
Jan 28 2017
,
Jan 28 2017
px is css pixels, not physical pixels. When you say "open any page at 989px screen width" is it in css pixels (aka dip) or physical pixels?
,
Jan 28 2017
In css pixels (or whatever is shown when you have the inspector open and resize the window).
,
Jan 28 2017
I just tested on CrOS and it seems to be working. What do you get for "window.innerWidth" on Windows + 125%?
,
Jan 28 2017
This is my console output, both calls fail to match. If it's correct on CrOS it must not be use-zoom-for-dsf related.
,
Jan 28 2017
Here is my result on Pixel 2 (I also tested on 1x dsf mode and got the same result). What if you change DPR within dev tools?
,
Jan 28 2017
No, it seems like it always reproduces here.
,
Jan 30 2017
Could it be 1.25x specific? Can you try 2.0 on windows?
,
Jan 30 2017
Disabling use-zoom-for-dsf is indeed a workaround, since the integer value of innerWidth becomes equal to the CSS pixels (from getComputedStyle or from getBoundingClientRect). Here's a test page to illustrate the difference between the values of innerWidth, getBoundingClientRect, getComputedStyle, and the value accepted by the width media query. Link, and attached: https://twister.43foldrs.com/media.html It's difficult to write a CSS breakpoint that selects between two mutually exclusive stylesheets. It's certainly more robust to use a CSS breakpoint to toggle just one stylesheet. (One reason is the min-width and max-width directives are >= and <=, respectively. This is sufficient to partition the integers but not to partition a real-valued space. Another is the lack of a device-pixel unit, to size a canvas in device pixels and have it displayed properly -- some scaling is nearly unavoidable. A possible workaround would be for media queries to round the viewport size in the same way as innerWidth. Naturally, those would all be breaking spec changes of various sorts; this mostly amounts to idle speculation.) Firefox seems to round off the CSS viewport for the purpose of media queries, in some way I haven't yet explored.
,
Feb 24 2017
,
Feb 24 2017
,
Mar 6 2017
Re: Comment #13 It can be reproduced at 1.25x, 1.5x and 1.75x, where width is a float number between 989px and 990px. Change the display to 2.0x, the error is gone.
,
Mar 7 2017
IMHO, under 1.25x or 1.5x condition, even if the screen width is manually set to 989px, it is not actually. These can be easily checked by clicking "Element" in dev tools. I have attached 3 screenshots. From the screenshots, we can see screen width is actually 989.600 under 1.25x, and 989.333 under 1.5x. As window.innerWidth will always left round the closest integer, it is 989.
,
Mar 13 2017
I'm not convinced our behavior is incorrect. The spec doesn't mention clamping fractional lengths as far as I can tell and in the given case, the viewport width does technically fall between the max and min ranges so returning false to both doesn't seem incorrect to me. Is this causing breakage on any real-world content?
As an additional data point, Firefox appears to work the same way. e.g. I sized the window to be 1688px wide. I then zoomed twice so window.devicePixelRation == 1.2000000476837158. This gives a viewport width of 1406.6666107707576. Here's how the mediaMatch calls looked:
MediaQueryList { media: "(max-width: 1406px)", matches: false }
MediaQueryList { media: "(min-width: 1407px)", matches: false }
MediaQueryList { media: "(min-width: 1406.9px)", matches: false }
MediaQueryList { media: "(min-width: 1406.4px)", matches: true }
+tabatkins@, any thoughts on what the correct behavior here should be?
,
Jul 31 2017
,
Sep 24
|
||||||||||
►
Sign in to add a comment |
||||||||||
Comment 1 by yeldi...@gmail.com
, Nov 22 2016