如何创建带固定div头部的滚动内容div?
固定头部+滚动内容的标准实现方案
需求说明
需要实现一个简单布局:
- 顶部标题div,仅展示标题文本
- 底部内容div,内容超出时可垂直滚动
现有方案分析
方案一:兄弟div结构
通过两个同级div分别作为头部和内容区,代码如下:
.header { background-color: lightgrey; height: 100px; } .content { background-color: grey; height: 100px; overflow-y: scroll; }
<div class='wrapper'> <div class='header'>I am the header</div> <div class='content'> <p>I can scroll</p> <p>I can scroll</p> <p>I can scroll</p> <p>I can scroll</p> <p>I can scroll</p> <p>I can scroll</p> </div> </div>
优点:结构语义化清晰,无定位脱离文档流的问题;
缺点:手动固定高度不够灵活,容器高度变化时需要重新调整数值。
方案二:嵌套+fixed定位
通过嵌套结构配合fixed定位实现头部固定,代码如下:
.wrapper { background-color: grey; height: 200px; display: flex; flex-direction: column; } .headerAndContent { flex: 1; background-color: darkgrey; overflow-y: scroll; } .header { position: fixed; }
<div class='wrapper'> <div class='headerAndContent'> <div class='header'>I am the header</div> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> </div> </div>
问题:fixed定位是相对于视口而非父容器,会导致头部脱离容器布局;同时未设置背景色时内容会穿透头部,还需手动给内容区添加padding避免被头部遮挡,维护成本高。
标准推荐实现
根据不同场景,推荐两种主流方案:
场景1:头部与内容区独立(头部固定不滚动)
使用Flex布局优化兄弟div结构,无需手动计算高度,自动适配容器空间:
.wrapper { height: 300px; /* 容器固定高度,可根据需求调整 */ display: flex; flex-direction: column; } .header { background-color: lightgrey; padding: 1rem; /* 高度由内容自适应,也可固定height */ } .content { flex: 1; /* 占据容器剩余所有空间 */ background-color: grey; overflow-y: auto; /* 内容超出时自动显示滚动条 */ }
<div class='wrapper'> <div class='header'>I am the header</div> <div class='content'> <p>I can scroll</p> <p>I can scroll</p> <p>I can scroll</p> <p>I can scroll</p> <p>I can scroll</p> <p>I can scroll</p> <p>I can scroll</p> <p>I can scroll</p> </div> </div>
该方案兼容性好,结构清晰,是此类布局的基础标准实现。
场景2:头部在容器内固定(滚动内容时头部留在容器顶部)
如果需要头部在容器范围内固定(而非视口),使用position: sticky是现代CSS的最优解,完美匹配“头部在内容块内布局自然”的需求:
.wrapper { height: 300px; overflow-y: auto; /* 容器整体允许滚动 */ } .header { position: sticky; top: 0; /* 相对于容器顶部固定 */ background-color: lightgrey; padding: 1rem; z-index: 1; /* 确保头部在内容上方,避免被覆盖 */ } .content p { margin: 1rem 0; }
<div class='wrapper'> <div class='header'>I am the sticky header</div> <div class='content'> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> <p>I am content</p> </div> </div>
sticky定位既保留了相对定位的文档流特性,又能在滚动到指定位置时固定,无需额外处理padding或高度计算。
内容的提问来源于stack exchange,提问作者713sean
相关产品推荐
相关产品推荐

