fixed侧边栏top值必须等于头部真实高度,如.pg-header计算高度为48px,则.menu的top必须设为48px;overflow-y:auto须加在内容区最外层容器且配height: calc(100vh - 48px),禁用body/html上overflow;必须用并设min-width保障可读性。

fixed侧边栏top值必须等于头部真实高度
很多人在写左侧菜单时直接写 top: 0,结果菜单盖住顶部导航条。这不是浏览器 bug,是布局逻辑没对齐。
关键点在于:如果 .pg-header 实际高度是 48px(含 padding、border、box-sizing 影响),那 .menu 的 top 就必须是 48px,不能靠“看着差不多”去猜。
- 用浏览器开发者工具 → Elements → 查看
.pg-header的 Computed 面板,找height值,这才是真实占用空间 - 如果用了
box-sizing: border-box且有padding: 12px,内容区高可能只有 24px,但总高仍是 48px —— 以 computed height 为准 - 写死
top: 50px在高 DPI 屏或缩放后容易错位,推荐用 CSS 变量或 JS 动态读取(如getBoundingClientRect().height)
overflow-y:auto 必须加在内容区,不是 body
侧边栏 fixed 后,主内容区若不设滚动控制,会出现两种典型问题:内容被裁剪不可见,或整个页面出现双滚动条(body + 内容区各一个)。
根本原因是 fixed 元素脱离文档流,内容区不再自动撑高,height: 100% 失效,必须显式限定高度并启用局部滚动。
- 正确写法:
height: calc(100vh - 48px); overflow-y: auto; - 禁止写
overflow: auto在body或html上 —— 这会让侧边栏跟着滚动,违背 fixed 本意 - Safari 对
overflow更敏感,不加overflow-y极易白屏或内容消失 - 如果内容区还嵌了 iframe 或第三方组件,要额外检查它们是否重置了
overflow
nav 标签不是可选,是可访问性强制要求
把左侧菜单写成 <div class="sidebar-menu"> 看似能跑,但对屏幕阅读器来说就是一堆无意义的 div。用户按 Tab 键无法跳过整块区域,也无法通过语义快速定位导航入口。<p><code><nav></nav> 是唯一被所有主流辅助技术识别为“导航地标”的原生标签,不替换就等于放弃键盘用户和视障用户。
- 必须用
<nav aria-label="系统功能菜单"></nav>,不能只写<nav></nav> - 如果页面同时有顶部主导航和左侧权限菜单,两个
<nav></nav>都得带不同aria-label,否则辅助技术无法区分 - 动态展开的二级菜单,需同步控制
aria-expanded="true/false"和aria-controls指向对应子菜单 ID - 当前激活项必须设
aria-current="page",不能只靠class="active"—— CSS 类名对辅助技术完全不可见
min-width 比 width 更关键
写 width: 20% 在小屏上会缩到文字挤成一团甚至看不见,这不是响应式失败,是忽略了最小可读边界。
左侧栏本质是操作入口,不是装饰性区域。宽度低于某个阈值后,图标和文字就失去可用性。
- 硬性建议:
width: 200px; min-width: 200px;—— 不要用百分比主导,尤其当右侧内容区也要弹性伸缩时 - 如果要做折叠/展开,用
width: 64px+min-width: 64px配合图标 hover 显示文字,而不是靠 JS 切换 class 控制 display - 字体大小变化、缩放比例(如 125%)、RTL 布局都会影响实际宽度需求,
min-width是兜底保障 - 别依赖媒体查询去“修复”小屏问题 —— 先确保
min-width能让最短菜单项完整显示文字
真正卡住后台左侧栏稳定性的,从来不是 JS 交互多复杂,而是这四件事:top 值有没有对齐 header 真实高度、overflow 是否落在正确容器、nav 有没有带 aria-label、min-width 有没有守住可读底线。漏掉任何一个,后续所有交互和动画都建立在沙堆上。











