Chrome浏览器scrollLeft赋值异常:是否为Bug及上报方式
问题与解答
问题描述
我有一个宽度为600px的#container,内部包含6个宽度为200px的div。同一时间仅显示3个div,其余可通过点击侧边按钮滚动查看,目前仅实现了右键滚动功能以聚焦问题。
通过for循环滚动容器时,每次将container.scrollLeft设为递增的整数(未用自增运算符以突出问题),但点击右键后控制台打印的container.scrollLeft值是错误的浮点数,Firefox中无此问题。请问这是否为Chrome的Bug?该如何上报?
更新发现:当设备像素比(DPR)为1.25时,Chrome中仅能将scrollLeft设为4的倍数;DPR为1.5625时,仅能设为16的倍数。规律是:首个与DPR相乘得自然数的正整数及其倍数,是scrollLeft仅能设置的整数值。
代码示例
JavaScript
let container = document.querySelector("#container"); let button_right = document.querySelector('#button_right'); let index; button_right.addEventListener('click', () => { if (container.scrollLeft >= 0) { for (index = 0; index < 296; index++) { container.scrollLeft = index; console.log(container.scrollLeft); } } });
CSS
* { box-sizing: border-box; padding: 0; margin: 0; border: 0; } body { display: flex; justify-content: center; } #container { width: 600px; height: 100px; /* border-style: solid; border-color: black; border-width: 2px; */ display: flex; align-items: center; overflow: hidden; } .sub { height: 75px; min-width: 150px; background-color: aqua; border-style: solid; border-color: black; border-width: 2px; } #button_right { margin-left: 8px; background-color: antiquewhite; width: 40px; font-weight: bolder; font-size: 25px; } #button_right:hover { cursor: pointer; }
HTML
<body> <div id="container"> <div id="sub1" class="sub"></div> <div id="sub2" class="sub"></div> <div id="sub3" class="sub"></div> <div id="sub4" class="sub"></div> <div id="sub5" class="sub"></div> <div id="sub6" class="sub"></div> </div> <button id="button_right">></button> </body>
解答
这不是Chrome的Bug,是像素对齐策略导致的行为差异
Chrome为避免亚像素渲染带来的模糊问题,会根据设备像素比(DPR)将滚动位置对齐到物理像素:
- 当DPR=1.25时,1个CSS像素对应1.25个物理像素,只有CSS滚动值为4的倍数时,乘以DPR后才是整数物理像素(4*1.25=5)
- 当DPR=1.5625时,需为16的倍数(16*1.5625=25),才能对应整数物理像素
Firefox的滚动位置处理逻辑不同,允许亚像素的CSS滚动值,因此不会出现这种对齐行为。
解决方法
若需精确控制滚动位置,可采用以下方式:
- 滚动到目标元素:使用
container.scrollIntoView({behavior: 'smooth', block: 'nearest', inline: 'start'}),让浏览器自动处理像素对齐 - 计算合规值:先获取当前DPR(
window.devicePixelRatio),计算最小整数n使得n*DPR为整数,再将目标滚动值调整为n的倍数 - 相对滚动:使用
container.scrollBy({left: 200, behavior: 'smooth'})这类相对滚动方法,避免直接设置scrollLeft绝对值
若仍需上报反馈
如果坚持认为这是问题,可通过以下方式向Chrome提交反馈:
- 在Chrome地址栏输入
chrome://feedback/打开反馈页面 - 详细描述问题:包括DPR与滚动值的对应规律、Firefox的对比表现、提供复现代码
- 上传代码片段或截图,明确说明预期行为与实际行为的差异
内容的提问来源于stack exchange,提问作者dRIFT sPEED
相关产品推荐
相关产品推荐

