本文介绍一种纯 CSS 实现方案,让容器内仅 .content 区域能够垂直滚动,而 .header 自适应高度、不固定、不依赖 position: absolute,适用于响应式布局和内容长度不确定的场景。
先看典型场景:一个容器中,头部高度不固定(可能包含多行文字、图片等),内容区需要独立滚动,且头部不能跟随滚动。常规做法要么将整个容器设为滚动,要么用绝对定位强行固定头部高度——但后者维护成本高,在响应式环境下容易出问题。其实有一种更简洁的思路,将滚动行为直接绑定到内容区自身,让头部自由伸展。
核心要点就一句话:不要把滚动容器设在外层 .block 上,而是让 .content 自己承担滚动职责,同时利用流式布局(例如 display: flex 或普通块级流)自然拆分头部和内容区域。
最简洁可靠的方案如下:
推荐写法(现代、语义清晰、兼容性好)
.block {
width: 800px;
border: 1px solid red;
/* 不设 height,不设 overflow,让 header 自由撑开 */
}
.header {
/* 无特殊定位,纯流式布局 */
padding: 12px 16px;
background-color: #f5f5f5;
font-weight: bold;
}
.content {
width: 100%;
height: 200px; /* 滚动区域固定高度 */
overflow-y: auto;
padding: 0 16px;
box-sizing: border-box;
}
注意几个关键细节:
- .content 必须设置一个明确的高度(例如 200px),否则 overflow-y: auto 不会生效——滚动需要边界条件。
- 这个高度与 .header 高度完全无关,因此头部可以任意长短,单行、多行、带图片都能正常显示。
- 千万不要给 .block 设置 height 或 overflow,否则会破坏自然流布局,导致整个容器一起滚动。
如果你希望内容区能自适应填充剩余空间(比如头部高度不固定,内容区占满父容器剩余部分),可以改用 Flex 布局:
.block {
width: 800px;
border: 1px solid red;
display: flex;
flex-direction: column;
max-height: 300px; /* 可选:限制整体最大高度 */
}
.header {
/* 自适应高度 */
padding: 12px 16px;
background-color: #f5f5f5;
}
.content {
flex: 1; /* 占据剩余所有空间 */
overflow-y: auto;
padding: 0 16px;
box-sizing: border-box;
}
这个 Flex 方案更加健壮:.header 高度完全由内部内容决定,.content 自动填充剩余空间并启用滚动,无需预设像素高度,真正实现了“可变头部 + 自适应滚动体”。
⚠️ 避免的误区
- ❌ 给 .block 设置 height + overflow: auto → 会导致整个区块滚动,不符合需求。
- ❌ 对 .header 使用 position: absolute → 会破坏文档流,导致高度不可预测,并引发无障碍访问问题。
- ❌ 仅对 .content 设置 overflow-y: auto 而不设置高度 → 滚动不会生效(auto 需要边界约束)。
总结一下:核心原则就是滚动行为应归属于内容容器自身,而非父容器;布局逻辑交由标准流或 Flex 处理,拒绝脱离文档流的 hack 手段。这样既能保持语义正确性,又具备良好的可维护性与可访问性。
