页面装完滚动条跳了一下我折腾了八年,今天 CSS 自己会留位置了——scrollbar-gutter 把这件事彻底收了
你有没有遇到过这种情况:页面上有个全屏布局的 sidebar,内容一多就出现滚动条,结果滚动条一出来页面就跳了一下——或者更烦的,滚动条消失的时候又跳一下。这就是我折腾了八年的那个坑。
以前解决这个,要么给容器写死 overflow-y: scroll(但这样永远显示滚动条,丑),要么用 JS 算滚动条宽度动态调整 padding(代码写得想哭),要么干脆躺平不管(用户骂就骂吧)。
现在 CSS 自己会处理这件事了。
scrollbar-gutter 是什么
这个属性是给文档根容器或者有滚动条的容器用的,作用是在滚动条出现之前就给它留好位置——不管滚动条在不在,布局都不会跳。
它的取值有两个:
/* 滚动条占用的空间永远保留,layout 不会因为滚动条跳 */
.scroll-container {
scrollbar-gutter: stable;
}
/* 滚动条出现时占用空间,消失时空间也消失 */
.scroll-container {
scrollbar-gutter: auto;
}
这两个值的区别主要在于「滚动条不在的时候留不留空」:stable 永远留,不管滚动条有没有;auto 则是没有滚动条时不留,有了才留。
实际效果对比
用 stable 模式的典型场景是全屏后台管理界面:
.layout-sidebar {
display: flex;
height: 100vh;
overflow: hidden;
}
.sidebar {
width: 240px;
overflow-y: auto;
scrollbar-gutter: stable;
border-right: 1px solid #e5e7eb;
}
.main-content {
flex: 1;
overflow-y: auto;
scrollbar-gutter: stable;
}
这样不管哪个 panel 的内容多或少,滚动条出不出,sidebar 和 main-content 的宽度永远固定,页面不会因为滚动条状态跳来跳去。
overlay 滚动条和经典滚动条的区别
这里有个细节要分清楚:macOS 默认用的是 overlay 滚动条,滚动条浮在内容上面,不占布局宽度;而 Windows 和 Linux 多数用的是经典滚动条,会占据实际的像素空间。
scrollbar-gutter 主要解决的是经典滚动条导致的 layout shift——因为经典滚动条真的会在文档流里占掉一块宽度。overlay 滚动条环境下,这个属性基本不影响布局。
如果你想确保行为一致,可以用 scrollbar-gutter: stable 强制给两种滚动条类型都预留空间,overlay 的滚动条会覆盖在预留空间上面,不会影响内容布局。
浏览器支持
Chrome 94+、Firefox 94+、Safari 16+ 都支持了。主流浏览器基本全绿,不用担心兼容性问题。
下一步
如果你的项目有全屏布局的管理后台,或者任何可能出现滚动条的容器,直接把 scrollbar-gutter: stable 写进去就行了。这个坑我填了八年,现在终于不用再折腾了。
评论区
登录后可评论。