用 position: sticky 可实现无 JS 的侧边栏滚动固定,需父容器设 min-height: 100vh 且不触发新层叠上下文;flex 布局解耦尺寸,侧边栏 flex: 0 0 240px,主内容 flex: 1;高亮当前项推荐 aria-current="page" + CSS;移动端收起用 max-height 过渡动画。

用 position: sticky 实现滚动时固定侧边栏
侧边栏菜单最常被忽略的是滚动行为——页面一拉,菜单就消失。用 position: sticky 是目前最轻量、无需 JS 的方案,但必须配合正确的父容器高度和定位上下文。
常见错误是直接给侧边栏设 sticky 却没限制其容器高度,导致“粘不住”。正确做法是:确保侧边栏的直接父元素有明确高度(比如 min-height: 100vh),且不触发新的层叠上下文(避免 transform 或 will-change)。
- 侧边栏元素加
position: sticky; top: 1rem; - 它的父容器设
display: flex; min-height: 100vh; - 不要在该父容器上加
overflow: hidden,否则 sticky 失效 - Chrome 和 Firefox 支持良好,Safari 15.4+ 才修复了部分 sticky 偏移 bug
用 flex 布局让主内容自动撑开宽度
很多人写侧边栏时手动写死主内容的 margin-left,结果响应式一换就错位。Flex 是更健壮的选择,它让主区域自动占据剩余空间,且能自然适配不同屏幕。
关键不是“怎么写侧边栏”,而是“怎么隔离侧边栏和主内容的尺寸耦合”。用 display: flex 父容器 + flex: 0 0 240px 控制侧边栏不缩放,主内容用 flex: 1 自动填满。
立即学习“前端免费学习笔记(深入)”;
- 父容器设
display: flex; width: 100%; - 侧边栏加
flex: 0 0 240px;(不伸展、不收缩、固定宽) - 主内容区加
flex: 1; overflow-y: auto;(防内容溢出) - 别用
float或inline-block,它们无法可靠控制剩余空间
点击菜单项后高亮当前项的 CSS 逻辑
纯 CSS 实现“当前页高亮”只有一种可靠方式:靠 URL 匹配 + :target 或服务端渲染 class。前端 JS 控制容易漏掉 history 回退、刷新等场景。
如果不想依赖 JS,推荐在服务端或构建时把当前路径对应的菜单项加上 aria-current="page",然后用 CSS 选中:
a[aria-current="page"] {
background-color: #007bff;
color: white;
}
- 不要只靠
.activeclass,它需要 JS 同步维护,易不同步 -
:target只适用于锚点跳转,不适用于 SPA 路由 - 若用 React/Vue,应在路由切换后显式更新
aria-current,而非仅靠 class - 无障碍要求下,
aria-current比纯视觉高亮更关键
移动端收起侧边栏时,用 max-height + overflow-hidden 做平滑折叠
用 display: none 切换会丢失所有过渡动画,用户感知生硬。真正可用的展开/收起动画得靠 max-height 配合 overflow: hidden,虽然要预估最大高度,但体验提升明显。
注意:不能用 height: 0 → height: auto,因为 auto 无法过渡。必须用固定值或足够大的 max-height(比如 max-height: 500px)。
- 默认状态设
max-height: 0; overflow-y: hidden; - 展开时设
max-height: 500px;(确保大于实际内容高度) - 加
transition: max-height 0.3s ease-in-out; - 别忘了在移动端用
aria-expanded同步控制可访问性


















