全出血布局的滚动条宽度 bug 终于被 CSS 修好了,container query units 实测
全出血布局的滚动条宽度 bug 终于被 CSS 修好了,container query units 实测
导语
如果你做过“全出血”风格的页面,大概率被这个问题折腾过:内容区域左右贴边很好看,但一放到有滚动条的页面里,右边就突然多出一段空白,整排文字对不齐。过去几年大家要么用 100vw hack,要么固定加 padding-right: 17px,但这两招本质都是在“赌”用户浏览器有没有滚动条。现在 CSS 终于给了更靠谱的解法,而且已经能稳定用。
正文
问题:全出血为什么会“翻车”
所谓全出血,就是把背景、图片或区块横向延伸到视口边缘,而内容区仍然居中。一个常见写法是:
.full-bleed {
width: 100vw;
margin-left: calc(50% - 50vw);
}
初看起来没问题,但一旦页面出现竖向滚动条,100vw 仍然包含滚动条宽度,背景就会向右“冒头”。反过来,如果你用 width: 100% 避免冒头,有滚动条时内容区又会变窄,文字行长不一致。
这是 CSS 里最经典的老问题之一,而且过去几乎没有纯 CSS 的优雅解法。
方案:container query units 才是正确答案
CSS Container Queries 除了能做响应式,还附带了一组容器单位:cqi、cqw、cqh、cqb。它们相对于容器尺寸计算,而不是视口。
用这个特性可以这样修全出血:
.content {
container-type: inline-size;
}
.full-bleed {
width: 100%;
margin-left: calc(-1 * cqi(50));
}
这里的 cqi(50) 表示“容器宽度的 50%”。容器就是 .content 自身的内容宽度,所以负边距刚好把区块拉回到视口边缘。而且因为参考的是内容容器,不是视口,滚动条不会再影响计算结果。
落地:最小可用的兼容写法
如果你需要更强的兼容控制,可以加一个基于 scrollbar-gutter 的稳定版:
html {
scrollbar-gutter: stable;
}
.section {
container-type: inline-size;
width: 100%;
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.full-bleed {
width: 100vw;
width: 100cqi;
margin-left: calc(50% - 50cqi);
}
scrollbar-gutter: stable 让浏览器提前预留滚动条空间,避免页面抖动。再配合 cqi,不管用户是否显示滚动条,全出血都能精确贴边。
对比:过去几种方案的坑
100vw:滚动条会让背景冒头,移动端尤其明显。- 固定
padding-right: 17px:只能适配某系统某浏览器的默认滚动条,换主题、换系统都会穿帮。 calc(100% + 2rem):在父容器和视口宽度接近时能蒙混过关,但复杂布局里依旧会出错。
相比之下,cqi 的好处是“相对于内容真实宽度做负偏移”,不再依赖视口或系统默认值。
结论
全出血布局这个十年老问题,现在终于可以用纯 CSS 稳定解决了。核心就两招:container-type: inline-size 建立容器上下文,cqi 做基于内容宽度的负偏移。再加上 scrollbar-gutter: stable 防抖动,基本可以淘汰过去那些滚动条 hack。
如果你还在项目里写 100vw 或者硬编码 padding,是时候换掉了。
收尾
下一步建议:挑一个有滚动条和无滚动条的页面各测一次,对比 100vw、固定 padding、cqi 三种写法的表现。你会发现 cqi 是唯一一个不用写断点、不用猜系统、不用 JS 兜底的方案。
评论区
登录后可评论。











