
本文介绍一种纯 css 方案,通过 `position: sticky` 结合嵌套布局,让左侧导航栏中的顶部和底部内容始终固定在视口内,无需 javascript,且能自动适配含固定头部的页面结构。
在构建现代响应式布局时,常需实现「左侧固定宽度导航栏 + 顶部固定 Header + 右侧主内容可滚动」的经典三栏结构。但一个常见痛点是:当希望左侧菜单整体撑满视口高度(100vh)的同时,又要求其中的顶部标题(如“TOP SIDER”)和底部模块(如“BOTTOM SIDER”)始终锚定在可视区域上下边缘——尤其当页面滚动、Header 移出视口时,它们仍需保持可见。
原方案中仅对 .sider 设置 height: 100vh 和 position: sticky; top: 0,虽能使整个侧边栏随滚动“粘住”顶部,但其内部子元素(.inner-sider)仍受限于父容器高度,无法独立响应视口边界变化。
✅ 正确解法是将粘性行为下放至具体子元素层级:
- 给顶部内容添加 position: sticky; top: 0;
- 给底部内容添加 position: sticky; bottom: 0;
- 同时确保其父容器(.inner-sider)具备 display: flex; flex-direction: column; justify-content: space-between;,以自然分配垂直空间。
这样,无论 .sider 是否受 Header 遮挡或滚动影响,.inner-top 始终紧贴视口顶部,.inner-bottom 始终紧贴视口底部,真正实现“智能自适应高度”。
以下是完整可运行代码(已优化语义与兼容性):
Sticky Left Sider Layout Header (Sticky)TOP SIDERBOTTOM SIDERMain Content Area
Scroll down to see how TOP and BOTTOM stay fixed in viewport.
⚠️ 注意事项:
- position: sticky 依赖最近的具有滚动约束的祖先容器;因此 .sider 必须有明确高度(如 100vh),且不能被 overflow: hidden 截断;
- 若 .sider 内部需支持菜单项滚动(如超长导航列表),建议在 .inner-sider 外层再包裹一层 div 并设置 overflow-y: auto,避免 sticky 元素被裁剪;
- top / bottom 偏移值(如 1rem)可用于规避 Header 遮挡,提升视觉体验;
- Safari 对 sticky 的兼容性较好,但旧版 iOS 需测试;如需极致兼容,可搭配 IntersectionObserver 回退方案(本文聚焦纯 CSS 解法)。
该方案简洁、高效、无 JS 依赖,完美契合现代 CSS 布局理念:用语义化定位替代脚本干预,让浏览器引擎自动处理滚动状态映射。










