
本文介绍一种纯 css 方案,通过 position: sticky 分别控制左侧导航中“顶部区域”和“底部区域”的定位行为,使其在页面滚动时始终可见,且无需 javascript,同时兼容 header 高度变化场景。
在构建带左侧导航栏(Sider)的响应式布局时,一个常见但易被忽视的需求是:左侧菜单需在垂直方向上“智能占满可视区域”,且其顶部和底部内容(如 Logo 和用户信息)应始终保留在视口内,不受页面滚动或顶部 Header 遮挡影响。直接设置 .sider { height: 100vh } 虽能撑满视口,但无法动态避开固定 Header 的占用空间;而使用 100% 高度又受限于父容器(.main)未设高度,导致失效。
解决方案的核心在于放弃对整个 .sider 设置统一高度,转而将定位逻辑下沉至内部子元素——利用 sticky 的独立锚点特性,让顶部和底部内容各自“粘住”视口边缘:
.inner-top {
position: sticky;
top: 0; /* 粘住视口顶部 */
z-index: 10; /* 确保不被其他元素遮盖 */
}
.inner-bottom {
position: sticky;
bottom: 0; /* 粘住视口底部 */
z-index: 10;
}同时,保留原有结构语义与 Flex 布局优势:
- .sider 仍设 height: 100vh 作为基础容器(确保足够高以触发 sticky 行为);
- .inner-sider 使用 flex-direction: column; justify-content: space-between 实现自然分隔;
- 无需 JS 计算 header 高度或监听 scroll 事件,完全声明式、高性能、可维护。
✅ 关键注意事项:
- sticky 元素必须有明确的“锚定边界”:.inner-sider 需具备高度上下文(100% 或 100vh),且其父容器(.sider)不能有 overflow: hidden;
- 若实际项目中 header 为 position: fixed,需额外为 .sider 添加 top: [header-height] 并配合 calc(100vh - [header-height]) ——但本例中 header 是普通流式元素,因此 sticky 可自然绕过它;
- 所有 sticky 元素需设置 z-index 避免被 content 层叠;
- 浏览器兼容性良好(Chrome 56+、Firefox 59+、Safari 15.4+、Edge 79+),旧版 Safari 可加 -webkit-sticky 前缀。
最终效果:无论页面是否滚动、Header 是否在视口中,“TOP SIDER” 始终贴顶,“BOTTOM SIDER” 始终贴底,左侧导航视觉上呈现“自适应全高”体验,且代码简洁、零 JS 依赖、语义清晰。










