div和ul远远不够。布局错位、响应式失效、点击穿透、滚动卡顿等问题,通常源于HTML结构与CSS作用域未对齐。下面直接拆解三个关键环节,帮你填平这些坑。
HTML结构必须语义化且支持嵌套控制
很多侧边栏一滚动就塌陷,根源在于将导航逻辑硬塞进aside或nav却不设置边界。浏览器默认将nav视为流式容器,内部ul的margin和padding容易外溢,导致整体偏移。
- 用
nav包裹主菜单,并立即添加role="navigation"防止部分屏幕阅读器误判 - 每个菜单项使用
li,内部链接必须包含href属性(即使只是#),否则键盘Tab焦点会跳过 - 如果有子菜单,使用嵌套
ul,但必须为父li添加aria-haspopup="true"和aria-expanded="false" - 避免将图标硬编码在HTML中,统一使用伪元素
::before或background-image控制,便于主题切换
CSS宽度与定位必须锁定根容器
侧边栏宽度不稳定、在flex布局中被压缩、在移动端突然撑满全屏——都是因为未切断父级影响。CSS的width和position必须有明确锚点。
- 给侧边栏最外层添加
flex-shrink: 0,防止在display: flex父容器中被压缩 - 使用
min-width而非width控制基础尺寸,例如min-width: 240px,兼容小屏折叠逻辑 - 使用固定定位(
position: fixed)时,务必同时设置top: 0和left: 0,否则在Safari中可能偏移 - 如果侧边栏需要随页面滚动,改用
position: sticky,但必须确保父容器有明确高度或overflow: visible,否则粘性定位失效
响应式切换别只靠@media,要配合HTML属性控制
仅用媒体查询隐藏/显示侧边栏,会导致DOM仍存在、焦点可抵达、屏幕阅读器仍播报——这不是真正的隐藏,而是“假装看不见”。真正的隐藏需要让浏览器和辅助技术都感知不到。
- 使用
data-collapsed="true"等自定义属性标记状态,CSS通过[data-collapsed="true"]选择器控制显示与隐藏 - JavaScript切换时,同步修改
aria-hidden和inert属性:el.setAttribute('inert', '')比display: none更彻底 - 移动端收起侧边栏后,记得给
body添加overflow: hidden,防止背景内容继续滚动 - 动画使用
transform: translateX()替代left,避免触发重排,尤其在低端安卓设备上更稳定
侧边栏最难的并非样式炫酷,而是每次交互后DOM结构、焦点顺序、ARIA状态、CSS渲染层这四者是否始终对齐——漏掉任意一个,用户就会卡在某个看不见的按钮上。
