最优解是html { scrollbar-gutter: stable; overflow-y: auto },必须作用于html元素且配合overflow-y: auto才生效;不支持时需兜底html { overflow-y: scroll },否则老浏览器仍抖动。

直接用 html { scrollbar-gutter: stable; overflow-y: auto } 是当前最可靠、最干净的解法;不支持时必须降级为 html { overflow-y: scroll },否则老浏览器里抖动照旧。
为什么只写 scrollbar-gutter: stable 没用
这个属性只对根滚动容器(即 html 元素)生效,设在 body、.app 或任何其他元素上都完全无效。更关键的是:它必须和 overflow-y: auto 或 overflow-y: scroll 同时出现,浏览器才会触发“预留滚动条空间”的逻辑。
- 常见错误:
html { scrollbar-gutter: stable }单独写 → 预留不计算,抖动依旧 - 常见错误:
.container { scrollbar-gutter: stable }→ 规范不认,CSS 被忽略 - 常见错误:
html { scrollbar-gutter: stable; overflow: hidden }→ 滚动被禁,scrollbar-gutter失效 - 正确写法必须是:
html { scrollbar-gutter: stable; overflow-y: auto }
兼容性兜底不能只靠 @supports
@supports (scrollbar-gutter: stable) 在 Chrome 94+、Firefox 97+、Safari 16.4+ 才识别;企业内网、旧版 Edge、定制 Chromium WebView 等环境会直接跳过整块规则,导致零兜底。
使用 Puppeteer + Chrome 将 HTML 渲染为中文 PDF,自动处理图表等待、Tab 展开、动画、测高、白边消除、防分页,适用于看板、报表、网页和交互图表转 PDF。
- 错误做法:只把
overflow-y: scroll写在@supports块里 → 老浏览器收不到这条声明 - 错误做法:没写基础声明,只靠
@supports覆盖 → IE 等连@supports都不解析,页面裸奔抖动 - 正确结构是先写兜底:
html { overflow-y: scroll } - 再用
@supports覆盖:@supports (scrollbar-gutter: stable) { html { overflow-y: auto; scrollbar-gutter: stable; } }
别碰 body { overflow-y: scroll }
很多教程建议给 body 加 overflow-y: scroll,但实际中容易出问题:某些 CSS Reset 库(如 Normalize.css)会重置 html 的 overflow,而 body 又不是根滚动容器,最终可能失效或引发双滚动条。
- 移动端尤其危险:
body不是根滚动上下文,iOS Safari 对它的overflow处理不一致 - 第三方组件库常偷偷操作
body.style.overflow,和你写的冲突 - 统一锁定在
html上:既符合规范,又避开大部分干扰 - 如果项目已用
body { overflow-y: scroll }且暂时没抖,不代表安全——模态框弹出、动态加载内容后很可能复发
真正难处理的不是你写的那几行 CSS,而是第三方 SDK 或 UI 库在挂载时悄悄读取 clientHeight、offsetWidth,又没做批量读取或防抖。这时候光靠 CSS 不够,得打开 Chrome DevTools 的 Performance 面板录一段滚动,看 Layout 事件是否密集爆发——抖动从来不是单点问题,而是渲染管线里多个微小操作叠加的结果。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










