grid 是侧边栏最干净方案:设 display: grid 和 grid-template-columns: 240px 1fr,侧栏固定宽、主内容自适应;用 position: sticky 实现悬浮,需父容器 min-height: 100vh;ie11 需降级为 table 布局+js 模拟 sticky。

侧边栏用 grid-template-columns 定死宽度,别靠 flex 或 float
Grid 是目前最干净的方案:侧栏宽度稳定、内容区自动占满剩余空间、无需计算 calc(100% - 240px)。关键在容器设 display: grid 和明确列轨道。
-
grid-template-columns: 240px 1fr—— 左栏固定 240px,右栏弹性撑满,比auto更可控 - 避免用
minmax(240px, 240px),看似保险,但某些旧浏览器(如 Safari 15.6 之前)对minmax固定值解析异常 - 如果侧栏要响应式收起,别改
grid-template-columns,而是用grid-column: 1 / -1让它横跨整行,再配合transform: translateX(-100%)动画更稳妥
悬浮效果靠 position: sticky,不是 fixed
position: fixed 会脱离文档流,导致右侧内容上移、滚动错位;sticky 才是真正“贴着父容器滚动”的行为,且天然支持 Grid 布局。
- 给侧栏加
position: sticky; top: 0;,前提是它的父容器(即 Grid 容器)有明确高度(比如min-height: 100vh),否则sticky不触发 - 常见错误:在 Grid 子项上直接写
height: 100%—— Grid 轨道不继承百分比高度,得用height: 100vh或min-height: 100vh - 移动端 Safari 对
sticky在 Grid 中的支持从 iOS 16.4 才完全稳定,低于此版本建议降级为position: relative+ JS 监听scroll补位
菜单项点击后高亮失效?检查 :focus-within 和 tabindex
纯 CSS 实现菜单项激活态时,很多人依赖 :hover,但键盘操作或点击后状态丢失,核心是没让元素可聚焦。
- 每个菜单
<a></a>或<button></button>必须有tabindex="0"(如果是<div> 等非可交互元素)<li>用 <code>:focus-within控制整个菜单容器的激活样式,比逐个写:focus更可靠,例如:.sidebar:focus-within .menu-item.active { background: #007bff; } - 别用
:visited判断路由激活——它只对真实跳转的链接生效,SPA 中的路由切换不会触发 - 容器设
display: table; width: 100%; table-layout: fixed;,侧栏和主内容分别用display: table-cell -
position: sticky在 IE11 中无效,必须用 JS:监听scroll,根据window.scrollY动态切position: fixed和position: static - 注意
table-cell的垂直居中默认是 middle,若菜单文字需顶部对齐,得加vertical-align: top
IE11 兼容?放弃 Grid,改用 display: table + position: sticky 回退
IE11 完全不支持 Grid 布局,强行 polyfill(如 css-grid-polyfill)会导致布局错乱和滚动卡顿,不如直接换方案。
Grid 方案看着简单,但真正上线时,sticky 的触发条件、IE 的降级路径、键盘焦点链路这三块最容易漏掉测试。尤其是侧栏在窄屏下被遮挡又没提供手动展开按钮,用户根本不知道菜单还存在。











