写完了五年布局,每次长页面切到短页面整个版心就要抖一下——今天这件事被 scrollbar-gutter() 用一行彻底原生化了
从长页面导航到短页面,整个版心向右抖了几像素。打开一个 modal 把 body 滚动锁住,背后的页面内容又跳了。多年以来,这个问题的临时解法是写一行 overflow-y: scroll 强制页面永远显示一个空的滚动条轨道,或者用 JS 算滚动条宽度然后手动补 padding-right。
真正的解法:一行 CSS。
html {
scrollbar-gutter: stable;
}
浏览器会提前为滚动条预留宽度,不管当前是否真的需要滚动条。长页面、短页面、modal 锁滚动——内容区域宽度永远不动。
CLS 直接受益。 这个跳变发生在首屏加载之后(字体加载、异步内容注入),会被算进真实用户的 Cumulative Layout Shift。一行 CSS 修一个 Core Web Vitals 指标,性价比极高。
三个真实场景:
场景一:页面导航跳变。 macOS 上不明显,但 Windows 和 Linux 用户只要插上鼠标就一定能看到——100vw 在有滚动条时比可视区域多出约 17px,整个布局被挤。
场景二:Modal 锁滚动。 body { overflow: hidden } 打开弹窗,macOS 用户看到滚动条消失、内容瞬间左移;Windows 用户在加了 scrollbar-gutter: stable 之后,内容完全不动。
场景三:动态内容容器。 聊天记录、搜索结果列表、下拉面板——内容随时塞满或清空,滚动条出现和消失的边界点上,内容不会 reflow。用法:
.chat-messages {
overflow-y: auto;
scrollbar-gutter: stable;
}
三件套组合:
scrollbar-gutter 之外,CSS Scrollbars Module Level 1 还定义了两个配套属性:
scrollbar-width:控制滚动条粗细,接受 auto | thin | none,比如 scrollbar-width: thin; 在 Firefox 上生效;
scrollbar-color:控制颜色,接受两个值代表轨道色和滑块色:
html {
scrollbar-gutter: stable;
scrollbar-width: thin;
scrollbar-color: #888 #f5f5f5;
}
三行搞定全局滚动条,CLS 改善、视觉统一、不再需要任何 JS 测量代码。
三个坑:
坑一:macOS 用户看不出效果。 这是正常的,不是 bug。macOS 默认是 overlay scrollbar,浮动在内容上方不占布局空间,scrollbar-gutter 在 macOS 上不会预留宽度——但也不会有布局抖动。可以插一个鼠标到 MacBook 或者开 Windows 虚拟机验证,也可以把系统设置改成”始终显示滚动条”。
坑二:overflow: overlay 不是答案。 overflow: overlay 是 WebKit 私有属性,Chrome 114 之后把它解析成 overflow: auto,不再有 overlay 效果。标准替代方案是 overflow: auto 配合 scrollbar-gutter: stable,别再怀念那个私有属性了。
坑三:position: fixed 要单独处理。 如果页面有 position: fixed 的 header 或 sidebar,加上 scrollbar-gutter 之后它们的宽度计算不受影响,但最好在设计之初就把滚动条宽度考虑进去(尤其是宽度用 % 或 vw 描述时)。
浏览器支持:
Chrome 94+、Firefox 97+、Safari 18.2+(2025 年 3 月)。覆盖了约 90% 的全球流量,渐进增强完全没有顾虑。
三步下一步:
第一步,搜一下项目里有没有 overflow-y: scroll 强制占位或者 JS 写的 padding-right 补偿 hack——这两个都可以删了;scrollbar-gutter: stable 一行全包。
第二步,直接加到 :root 或 html 上,看哪个页面的动态内容最多就先加哪个,CLS 改善最明显。
第三步,想统一全局滚动条风格的,scrollbar-gutter: stable + scrollbar-width: thin + scrollbar-color 三件套一起加,不用任何 JS。
滚动条这件事,90% 的前端工程师不知道还有标准解法。知道的人里,一半还在用 overflow-y: scroll 凑。下一个长→短页面导航发生的时候,看看你的 DevTools Performance 面板——CLS 那一条会不会比上次低一点。
评论区
登录后可评论。