CSS Handbook · 布局

第六章 / 6.2 overflow 与滚动容器

第六章 · 6.2 节

overflow 与滚动容器


当子内容尺寸超出容器时该怎么办,是布局中绕不开的问题。overflow 决定了"溢出的部分是显示、裁剪,还是变成可滚动区域",同时它还会悄悄触发一个重要的副作用——创建新的块格式化上下文(BFC)。

overflow 的取值

取值效果
visible(默认)溢出内容照常显示,不裁剪、不产生滚动条
hidden溢出内容被裁剪且不可见,也无法通过滚动查看
scroll始终显示滚动条(即使内容未溢出),裁剪溢出内容
auto仅在内容溢出时才显示滚动条,最常用的取值
clip类似 hidden,但禁止编程式滚动(如 scrollTo),性能更好
overflow: auto 效果
这是一段足够长的文字,用来撑爆容器的高度,从而演示 overflow: auto 在内容溢出时才出现滚动条的行为——继续往下滚动就能看到全部内容。这里再补一句凑够长度。

分轴控制

overflowoverflow-xoverflow-y 的简写,可以分别控制两个方向:

.gallery {
  overflow-x: auto;  /* 横向可滚动,常用于图片走廊 */
  overflow-y: hidden; /* 垂直方向裁剪,不产生纵向滚动条 */
  white-space: nowrap;
}
注意两个方向只要有一个不是 visible,另一个即使设置为 visible 也会被自动计算为 auto——浏览器不允许"一个方向裁剪、另一个方向内容还能随意溢出跑到裁剪区域外"。

overflow 与 BFC

给容器设置除 visible/clip 之外的 overflow 值,会让它成为一个新的块格式化上下文(Block Formatting Context)。这是早期最常用的"清除浮动"手法之一——父元素触发 BFC 后,会正确包裹住内部的浮动子元素高度。完整的 BFC 触发条件与浮动布局见 6.5 浮动与 BFC

.clearfix-legacy {
  overflow: hidden; /* 触发 BFC,父元素高度重新包住浮动子元素 */
}

overscroll-behavior

控制滚动到容器边界后,是否将滚动"传导"给父级或整个页面——典型场景是防止弹层内部滚动到底部后,继续下滑触发背后页面的滚动(俗称"滚动穿透")。

.modal-body {
  overflow-y: auto;
  overscroll-behavior: contain; /* 滚动到边界后不再传导给页面 */
}

scrollbar-gutter 与滚动条布局抖动

内容变化导致 overflow: auto 的容器在"有滚动条"和"无滚动条"之间切换时,非覆盖式滚动条(如 Windows 默认样式)会占用布局空间,造成内容左右抖动。scrollbar-gutter 可以提前预留这部分空间:

.list {
  overflow-y: auto;
  scrollbar-gutter: stable; /* 无论是否出现滚动条,都预留其宽度 */
}

层叠上下文速查

z-index 与层叠上下文的完整讲解见 6.1 盒模型与定位,这里补充一份速查表,列出会创建新层叠上下文的常见触发条件:

  • position 为 relative/absolute/sticky/fixed 且显式设置了 z-index(非 auto)。
  • opacity 小于 1。
  • transformfilterperspective 取值不为 none。
  • will-change 指定了以上任一属性。
  • flex/grid 容器的子项,且 z-index 不为 auto。
  • isolation: isolate——不改变任何视觉效果,唯一作用就是显式创建一个新的层叠上下文,常用于隔离某个组件内部的 z-index,避免影响页面其他区域。

常见误区

  • 给弹窗/抽屉设置 overflow: hidden 想裁剪内容,却意外裁掉了子元素的 box-shadow 或 tooltip——这类"溢出但需要可见"的视觉效果,应考虑用额外的包裹层隔离 overflow。
  • 忘记 overflow: hidden 会创建 BFC,导致容器内原本设计为"溢出可见"的子元素被意外裁剪。
  • 用很大的 z-index(如 9999)暴力解决层级问题,而没有意识到真正的原因是某个祖先创建了限制性的层叠上下文。