:checked ~ .submenu不展开最常见原因是input与.submenu不在同一父元素下且非直接兄弟;多级菜单需每级独立绑定唯一id的input;max-height动画须设固定值并配合overflow:hidden和transition;可访问性要求input可聚焦、label显式关联且aria-expanded同步更新。

为什么:checked ~ .submenu有时完全不展开
最常见原因是 DOM 结构没对齐:input 和目标 .submenu 不在同一个父容器下,或者中间插了其他元素(比如 <span></span>、文字节点、<div class="divider">)。<code>~ 选择器只匹配“后续兄弟”,不是“后代”,更不是“任意位置的同名元素”。
-
input必须在 HTML 中物理位置出现在.submenu之前 - 两者必须是同一父元素的直接子节点(例如同在
<li>或<ul></ul>下) - 如果结构是
<label><input></label><ul class="submenu"></ul>,那input:checked ~ .submenu有效;但如果是<label><input><ul class="submenu"></ul></label>,就失效——因为.submenu是input的后代,不是兄弟 - 调试时打开浏览器开发者工具,右键检查
.submenu元素,看它和最近的input是否显示为“同级”
多级菜单里子菜单无法随父级联动收起
CSS 没有“父级状态影响子级样式”的机制,:checked 只能向下作用,不能向上或跨层广播。所谓“联动收起”,其实是靠每一级都独立监听自己的 input:checked 状态,而不是指望父级一关、子级自动消失。
- 每个
.submenu都必须绑定到它**直属的**input,不能复用父级的id或name - 错误写法:
#nav-toggle:checked ~ .submenu, #nav-toggle:checked ~ .submenu .submenu { max-height: 500px; }—— 这会让所有子级无条件展开,失去控制粒度 - 正确做法:给每级菜单配唯一
id,如node1、node1-1、node1-2-1,再分别写#node1:checked ~ .submenu、#node1-1:checked ~ .submenu - 别试图用
:not(:checked) ~ .submenu来“反向收起”——它不工作,CSS 不支持否定伪类驱动后续元素隐藏
max-height过渡动画卡顿或跳变
移动端 Safari 和部分安卓 WebView 对 max-height 过渡渲染不稳定,尤其当值从 0 跳到 auto 时会直接闪现,或在展开中途突然截断。
- 绝对不要写
max-height: auto—— 它无法过渡,浏览器会退回到max-height: none,动画中断 - 必须设一个“足够大但不过分夸张”的固定值,如
max-height: 400px(根据最多 5–6 项估算) - 配合
overflow: hidden和transition: max-height 0.3s ease,缺一不可 - 加
will-change: max-height到.submenu元素上,让浏览器提前启用 GPU 加速(iOS 15+ 和 Chrome 90+ 有效) - 如果内容高度差异极大(比如含图片或动态文本),优先考虑改用
transform: scaleY()+opacity组合,比max-height更稳
键盘用户无法用空格切换、屏幕阅读器读不出状态
纯 CSS 方案容易忽略可访问性,导致键盘焦点停在 label 上却无法触发菜单,或 aria-expanded 没同步更新。
-
input[type="checkbox"]必须可聚焦:禁用display: none,改用position: absolute; left: -9999px或clip-path: inset(100%) -
label必须通过for属性或嵌套方式与input显式关联,大小写严格匹配 - 手动补
aria-expanded:在label上加aria-expanded="false",再用 CSS 伪类切换(需 JS 辅助):#node1:checked + label { aria-expanded: "true"; }不生效,得靠 JS 监听change事件更新属性 - 移动端 Safari 有时不响应空格键切换,可在
input上加tabindex="0"强制可聚焦
实际落地时,最易被忽略的是「每一级 input 都要独立存在且 ID 唯一」——复制粘贴一套代码却不改 id 和 for,结果只有第一级能动。











