
本文介绍一种纯 css 方案,通过 position: sticky 分别控制侧边栏内顶部与底部元素的定位,使左侧导航在滚动时始终显示“top sider”和“bottom sider”,且自动适配 header 是否可见,无需 javascript。
在构建响应式布局时,常需实现「左侧固定宽度导航栏 + 顶部固定 Header + 右侧可滚动内容」的经典三栏结构。但一个常见痛点是:若直接对 .sider 设置 height: 100vh,会导致其高度始终基于视口而非可用内容区域,当页面存在固定 Header 时,“底部锚点”(如版权、快捷入口)会因超出视口而不可见;而若改用 100% 又受限于父容器未设高度,无法生效。
核心解法:不约束 .sider 整体高度,而是对内部子元素分别应用 sticky 定位:
- .inner-top 使用 position: sticky; top: 0 —— 始终吸附在容器顶部(即 header 下方或视口顶部,取决于滚动位置);
- .inner-bottom 使用 position: sticky; bottom: 0 —— 始终吸附在容器底部(即视口底边),即使 .sider 内容高度不足,也能保持可见。
✅ 优势:
- 纯 CSS 实现,零 JS 依赖,性能轻量;
- 自动响应滚动:header 滚出视口后,.inner-top 会自然贴附视口顶部;反之则停驻在 header 下方;
- 兼容现代浏览器(Chrome 56+、Firefox 59+、Safari 15.4+、Edge 79+);
- 不破坏 Flex 布局流,不影响右侧 .content 的正常滚动行为。
? 示例代码(关键 CSS 片段):
.inner-top {
position: sticky;
top: 0;
background-color: #4a6fa5; /* 可选:增强视觉区分 */
padding: 8px 12px;
z-index: 10;
}
.inner-bottom {
position: sticky;
bottom: 0;
background-color: #3a5a8c;
padding: 8px 12px;
z-index: 10;
}⚠️ 注意事项:
- 确保 .sider 的父容器(即 .main)不设置 overflow: hidden 或 overflow: auto,否则会截断 sticky 元素;
- .inner-sider 必须保留 display: flex; flex-direction: column; justify-content: space-between,以维持初始布局逻辑;
- 若 .sider 内需嵌入长菜单(非仅两个锚点),建议将菜单容器设为 flex: 1 并启用 overflow-y: auto,确保中间区域可滚动,而 top/bottom 元素仍 sticky;
- 在 Safari 中,需确保 sticky 元素的祖先节点无 transform、filter 或 perspective 等属性(会创建新的层叠上下文,导致 sticky 失效)。
该方案优雅地规避了动态计算高度的复杂性,让左侧导航真正“智能贴边”,是现代 CSS 布局中 sticky 定位的典型实践范例。










