结论:用 checkbox + label 模拟开关,配合 @media 控制断点,transform 和 transition 实现三条线动画,比 js 更轻量可靠;它避免 dom 时机问题、移动端 click 延迟与 focus 失效,天然支持键盘 enter 和无障碍访问。

直接说结论:用 checkbox + label 模拟开关,配合 @media 控制显示断点,再用 transform 和 transition 实现三条线动画,比 JS 更轻量、更可靠。
为什么不用 JavaScript 控制菜单显隐?
纯 CSS 方案避免了 DOM 操作时机问题(比如 DOMContentLoaded 未触发时点击无响应),也绕开了移动端 click 延迟、focus 失效等兼容性坑。关键是:它天然支持键盘 Enter 触发(checkbox 可聚焦可回车),无障碍支持更好。
常见错误现象:document.getElementById('menu-toggle').click() 在 iOS Safari 中可能静默失败;JS 绑定 touchstart 又容易误触。
实操建议:
- 把
input[type="checkbox"]放在label前面,利用 HTML 隐式关联(for/id不是必须的) - 用
position: absolute; clip: rect(0 0 0 0);隐藏 checkbox,别用display: none(会彻底移出可访问树) - 确保
label足够大(至少 44×44px),满足移动端触控热区要求
三条线怎么用纯 CSS 动画实现?
核心是把三根“线”写成 ::before、::after 和元素本身,统一用 background 或 border 绘制,再通过 transform 旋转/位移来模拟折叠效果。不能依赖 SVG 或图片,否则缩放或高 DPR 屏幕下易模糊。
使用场景:需要在小屏展开为「X」,大屏自动隐藏汉堡包、显示完整导航栏。
实操建议:
- 用
box-sizing: border-box确保 padding 不影响线条高度计算 - 动画必须加
transition: transform 0.3s ease, opacity 0.3s ease,只过渡 transform 性能更好 - 收起状态:中间线保持水平,上下线分别旋转 -45deg / +45deg 并位移到中线位置;注意
transform-origin: center要设对,否则旋转偏移
响应式断点怎么设才不踩坑?
别用固定像素值如 max-width: 768px —— iPad Pro 横屏是 1024px,但很多桌面浏览器窗口也能缩到那么窄,导致菜单错乱。应该按内容决定断点,而不是设备。
性能影响:过多 @media 查询不会拖慢渲染,但嵌套过深的媒体查询(尤其带 and (hover: hover))在旧 Android 浏览器里可能被忽略。
实操建议:
- 用
em或rem设断点,例如@media (max-width: 48em)(对应 768px / 16px) - 菜单展开区域用
position: fixed时,务必加top: 0; left: 0; width: 100%; height: 100%,否则在 iOS Safari 中滚动时可能错位 - 在大屏下,用
:checked ~ nav { display: flex }显示完整导航,同时把汉堡包display: none,别只靠opacity: 0(仍占布局空间)
最常被忽略的一点:checkbox 的 :checked 状态在页面刷新后不会保留。如果需要记忆用户偏好(比如默认展开),得额外用 localStorage 配合少量 JS —— 但那已是增强功能,不是折叠菜单本身必需的。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











