纯CSS汉堡图标形变需用input[type="checkbox"]触发:checked状态,三条线统一transition: transform 0.3s ease, opacity 0.3s ease;顶部线顺时针转45°、底部逆时针转45°、中间线opacity:0或scale(0),transform-origin均设为50% 50%,span用top:50%;transform:translateY(-50%)垂直居中。

用 transform 和 transition 控制三条线的旋转与位移
纯 CSS 实现汉堡图标(☰)到关闭图标(×)的形变,核心不是“画两个图标来回切换”,而是让三条水平线各自做不同的 transform 动画:顶部线顺时针转 45°、底部线逆时针转 45°、中间线淡出或缩放为 0。所有动画必须共享同一组 transition 属性,否则会出现不同步卡顿。
常见错误是只给单条线加 transition,结果三条线动画延迟不一致;或者用 display: none 隐藏中间线——这会破坏过渡,因为 display 不可动画。
实操建议:
- 用一个容器包裹三条
,统一设置transition: transform 0.3s ease, opacity 0.3s ease - 中间线不用
display,改用opacity: 0或transform: scale(0) - 确保初始状态三条线垂直居中对齐,用
top: 50%; transform: translateY(-50%)比margin-top更可靠
必须用 input[type="checkbox"] 触发状态切换
CSS 本身没有“点击事件”,所以得靠表单控件的伪类来驱动样式变化。最稳妥的方式是用隐藏的 input[type="checkbox"] + label,通过 :checked 伪类控制菜单线条的变形状态。别用 :hover 或 JavaScript 模拟——前者无法保持状态,后者就不是“纯 CSS”了。
容易踩的坑:
-
label没绑定for或没包住input,导致点击无响应 - 把
input设为visibility: hidden而不是position: absolute; opacity: 0,某些浏览器下会丢失焦点/可访问性 - 在移动端,
label点击区域太小,没加min-height或padding,导致点不中
transform-origin 必须设为线条中心点
三条线旋转时如果没设 transform-origin,默认以左上角为原点,转出来会偏移、错位。每条线都应设为 transform-origin: center(或等价的 50% 50%),确保旋转轴心在自身几何中心。
注意兼容性细节:
- 旧版 Safari 对
transform-origin: center支持不稳定,建议写成transform-origin: 50% 50% - 如果线条用
border-bottom模拟,它的视觉中心和盒模型中心可能不重合,优先用height+background实现更可控 - 不要依赖父容器的
text-align: center来居中线条——它只影响内联元素,而span默认是内联,但一旦加了transform就可能触发 BFC 变化
移动端真机测试时要注意 click 延迟和 focus 样式残留
纯 CSS 汉堡菜单在 iOS Safari 上常出现点击无响应或第二次才生效,根本原因是 input[type="checkbox"] 在触摸设备上需要明确的可点击区域和 focus 状态管理。不处理的话,用户第一次点可能只聚焦没触发 :checked。
解决方案很具体:
- 给
label加cursor: pointer和-webkit-tap-highlight-color: transparent - 在
input:checked + label后续选择器里,确保变形样式不被其他规则(比如全局a:focus)意外覆盖 - 避免在
label上同时写:active和:checked的复杂组合,容易在快速连点时状态错乱
真正难调的不是动画本身,而是 checkbox 状态在 touchstart/touchend 之间的微小窗口期 —— 这部分没有任何 CSS 能干预,只能靠 DOM 结构干净、选择器精准来规避。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











