Subpixel scroll issue, can't set scrollTop pro

2019-07-07 07:07发布

问题:

I'm trying to set scrollTop property of some DOM element programmatically and I have weird behaviour that breaks my tests in some specific environment. I created minimal repro (the link)

HTML

<div id=viewport><div id=content></div></div>

CSS

#viewport {
  overflow-y: auto;
  height: 20px;
}
#content {
  height: 150px;
}

JS

const viewport = document.getElementById("viewport");
viewport.scrollTop = 75;
console.log(viewport.scrollTop);

The result of the script is broken on Chrome 69.0.3497.100 running on Win 10 Pro. It is 74.4000015258789 instead of 75. It works properly on the same Chrome version on Mac and even on Win 10 Home running under VirtualBox. Firefox and Edge also have no such an issue.

I know it looks very strange, but what could it be? Can anyone confirm this problem? And could it be fixed in some way to make sure that the result of the scrollTop assignment is exactly I want it to be?


Update. Thanks to @khajjit, I was able to reproduce the issue on my Mac machine and got 74.66666412353516 on 75% zoom out and 150% zoom in. 80% gives 75, 90% -- 74.44444274902344, 110% -- 74.54545593261719 etc (I updated the demo to show the results table). So the issue does not relate to OS. But it looks like the Chrome only issue. Firefox and Edge return 75 at any scale.

Update 2. Scaling the screen resolution at the OS layer also affects the situation. That was the case of Win 10 Pro described above; it had 125% OS scaling.

So the practical part of the question is how to overcome Chrome scaling rounding issues to be able to set scrollTop precisely?


Update 3. Chromium Dev confirmed that this is a bug:

This issue is because Chrome does not fully support fractional scroll offset.

So if someone is interested in this problem resolving, please follow the link and star the issue on the Chromium end.

回答1:

I think it might be related to the resolution of the monitor.
I have a resolution of 1920x1080 and with a scale of 100% the result is 75.
But if you set 75% or 150%, the result will be 74.66666412353516.
Or say 25%, the result will be exactly 74.


I don't have any exact answer as to what it might be related to, but I think this little research might lead to the right path.