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

[ResizeObserver] with device pixel content box does not take into account visualViewport.scale #11412

Open
greggman opened this issue Dec 24, 2024 · 1 comment

Comments

@greggman
Copy link

ResizeObserver is supposed to return devicePixelContentBox which is the number of device pixels of an observed element's content box. But, if you pinch to zoom (Chrome Mac, 2 finger or AFAIK any Android phone), the number of device pixels changes but ResizeObserver's event is not fired nor does the actual reported size of devicePixelContentBox change if you refresh a pinch to zoom page.

This means you can't actually get the correct device pixels. You can multiply by scale but you end up with the same problem devicePixelContentBox was designed to solve.

Can this be fixed?

@greggman
Copy link
Author

greggman commented Jan 9, 2025

You want device pixels so you can be pixel perfect. The user pinches to zoom (testing on M1 Mac). ResizeObserver does not actually return device pixels even though it's named devicePixelContentBox. Multiplying that value by visualViewport.scale doesn't solve the problem.

Here's a repo of the issue: https://greggman.github.io/doodles/test/devicepixelcontentbox-with-visualviewport-scale/dpr-zoom-test-with-visualviewport.html

If the calculation is perfect then you should see solid stripes, orange and cyan. If the calculation is not perfect then you'll see a gradient of color (orange to dark orange), cyan to dark cyan). If you turn on image-rendering: pixelated then you'll see some line is doubled because the calculation is not perfect.

Here's a video: Unfortunately, compression artifacts might not make it clear things are not correct (it also changed the colors to pink and blue 🤷‍♂️). But, you can run the test yourself. Open the test above on a Mac. See, by default, the colors are solid. Pinch to zoom on the trackpad. See the colors stop being solid (because devicePixelContentBox * visualViewport.scale does not return the actual number of device pixels so the page can't correctly render a perfect match for the device). It's best to pinch to zoom with the cursor over the info box, otherwise it will get pushed offscreen.

Screen.Recording.2025-01-09.at.12.50.39.mov

Note that in the video, switching to ceil or round looks better but if you look closely you'll see the color on the right is not the same as the color on the left. This is more easy to see if you do it live.

In any case, given the value is called devicePixelContentBox it seems like it should actually return "device pixels" and not some other value. Can we update to spec to say it should take visualViewport.scale into account and do whatever is necessary to return the actual "device pixels"? Or add a new actualDevicePixelContentBox and deprecate the existing one?

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

No branches or pull requests

2 participants