:checked是唯一能稳定映射“开/关”语义的原生DOM状态,而click事件易引发竞态导致状态不同步,如input.checked=true未触发浏览器原生状态更新,使#toggle:checked~.menu等CSS规则失效。

为什么用 :checked 而不是 click 事件控制状态
因为纯 CSS 交互必须依赖可被伪类捕获的 DOM 状态,:checked 是唯一能稳定映射“开/关”语义的原生状态;JS 的 click 会引入竞态:比如手动调用 input.checked = true 却没触发浏览器原生状态同步,导致后续 #toggle:checked ~ .menu 规则不生效。真实项目里最常复现的“点两下才动”问题,八成出在这里。
max-height 过渡失效的三个典型表现
菜单展开瞬间闪现、无动画、或只动一半——基本是 max-height 值设小了或漏了 overflow: hidden。SCSS 里别写死 500px,改用变量加足够余量:
-
$menu-max-height: 600px;(按最多 12 个菜单项预估) - 初始状态必须同时声明:
max-height: 0; overflow: hidden; - 展开状态写
max-height: $menu-max-height;,不能用auto - iOS Safari 对
max-height过渡偶有抖动,加will-change: max-height;到菜单容器上
三条线变形动画在 SCSS 中怎么避免重复代码
用 @mixin 抽离共性,但每条线的 transform 必须独立控制——顶部线转 +45° 并下移,中间线透明,底部线转 -45° 并上移。错误做法是给整个 .hamburger 加 transform,结果三线粘连旋转。
推荐结构(含关键注释):
立即学习“前端免费学习笔记(深入)”;
@mixin hamburger-line {
display: block;
width: 24px;
height: 2px;
background: currentColor;
transition: transform 0.3s ease, opacity 0.2s ease;
transform-origin: center;
}
.hamburger__top { @include hamburger-line; }
.hamburger__mid { @include hamburger-line; }
.hamburger__bottom { @include hamburger-line; }
#menu-toggle:checked + .hamburger .hamburger__top {
transform: rotate(45deg) translateY(6px);
}
#menu-toggle:checked + .hamburger .hamburger__mid {
opacity: 0;
}
#menu-toggle:checked + .hamburger .hamburger__bottom {
transform: rotate(-45deg) translateY(-6px);
}
注意:translateY(6px) 和线间距保持一致,否则变形时错位;transform-origin: center 必须显式写,Safari 不认默认值。
移动端点击区域小、响应延迟怎么修
不是加 padding 就完事——iOS Safari 默认有 300ms 点击延迟,且 label 热区太窄时手指容易滑脱。实际生效的组合是:
-
label上加touch-action: manipulation; -
label内部元素(如图标)设cursor: pointer; - 隐藏的
input[type="checkbox"]用position: absolute; opacity: 0; pointer-events: none;,别用display: none(会砍掉键盘焦点和读屏支持) - 如果用伪元素画线,
::before/::after必须带content: "";,否则不渲染
复杂点在于:所有动画属性(transform、opacity、max-height)必须写在被切换的元素上,而不是父容器;兄弟选择器路径(~ 或 +)一旦写错层级,整个动画就静音——这点没法靠编译报错发现,得靠 DevTools 强制触发 :checked 状态来逐层验证。


















