纯css侧边滑动菜单必须用input[type="checkbox"]+:checked触发,因其原生支持键盘/无障碍且零js依赖;动画须用transform: translatex()配合transition,避免重排;遮罩需同级label绑定并设fixed全屏。

侧边滑动菜单不是靠“手把手教学”堆出来的,而是靠 transform + transition 控制位移、用 checkbox 或 input[type="checkbox"] 做状态开关——不依赖 JavaScript 才真正稳定、可访问、易调试。
为什么用 checkbox 而不用 click 事件?
纯 CSS 实现的菜单,核心是把“展开/收起”变成一个可被 CSS 选择器捕获的布尔状态。原生 checkbox 的 :checked 伪类就是最轻量、最可靠的状态钩子:
-
checkbox支持键盘空格切换、屏幕阅读器识别,无障碍基础比div + click强得多 - 没有 JS 就不会因脚本加载失败或执行错误导致菜单卡死
- 样式切换完全由浏览器渲染引擎调度,动画更顺滑(尤其是移动端)
- 避免在
document.addEventListener("click")里反复判断点击区域、阻止冒泡等易出错逻辑
transform: translateX() 比 left 或 margin-left 更合适
用 left 或 margin-left 触发重排(reflow),动画会掉帧;而 transform 只触发重绘(repaint),GPU 加速更稳:
- 菜单容器设
position: fixed或absolute,再用transform: translateX(-100%)初始隐藏(向左移出视口) - 勾选
checkbox后,通过.menu:checked ~ .sidebar { transform: translateX(0); }拉回 - 必须加
transition: transform 0.3s ease,否则位移无动画 - 别忘了给
.sidebar设will-change: transform(可选,对长列表滚动有帮助)
遮罩层(overlay)怎么和菜单联动?
遮罩不是装饰,它解决两个实际问题:防止背后内容被误点、视觉上明确“当前焦点在菜单”:
- 遮罩元素(
.overlay)必须紧跟在checkbox后面,才能用兄弟选择器.menu:checked ~ .overlay控制显隐 -
.overlay设display: none初始隐藏,:checked时改为display: block并加background: rgba(0,0,0,0.5) - 遮罩要设
z-index在菜单之下、主内容之上(比如z-index: 99),否则点不到菜单里的链接 - 给遮罩加
cursor: pointer,并绑定label[for="menu"]或直接用input隐藏后点击遮罩关闭菜单
移动端适配最容易漏的三件事
桌面端能跑,不等于手机上可用:
- 菜单宽度别写死
width: 250px,改用width: 80vw或min-width: 280px,避免小屏被撑破 - 必须加
viewportmeta:<meta name="viewport" content="width=device-width, initial-scale=1">,否则vw单位失效 -
touch-action: manipulation加在菜单和遮罩上,减少 iOS 点击 300ms 延迟
真正麻烦的从来不是写几行 CSS,而是当用户用手指划过遮罩、同时又想拖拽页面、还点了菜单里带下拉的二级项时,各状态如何不打架——这时候,checkbox 的原子性就比任何 JS 状态机都省心。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











