:checked 是唯一可靠触发机制;HTML 需满足 DOM 顺序、label 绑定、隐藏方式三条件;input 必须前置且用绝对定位隐藏;选择器用 + 或 ~ 取决于结构紧邻性;下拉内容初始状态用 visibility/height/opacity 组合,过渡仅限 opacity 或 transform;name 属性错误会导致静默失效。

纯 CSS 实现点击下拉菜单,:checked 是唯一可靠、可维持、可访问的触发机制;其他方案(如 :hover)在移动端失效或不支持键盘焦点,而 JS 方案则违背“轻量交互”初衷。
HTML 结构必须满足三个硬性条件
DOM 顺序、label 绑定、隐藏方式,三者任一出错都会导致样式完全不响应,且浏览器不报错。
-
<input type="checkbox" id="menu-toggle">必须出现在<label>和下拉内容之前,且同级 -
<label for="menu-toggle">的for值必须与 input 的id完全一致(大小写敏感、无空格) -
input不能用display: none隐藏——这会让屏幕阅读器跳过,也破坏空格键触发能力;应改用:position: absolute; opacity: 0; width: 1px; height: 1px; margin: -1px;
~ 和 + 选择器怎么选?
关键看下拉内容是否紧贴在 input 后面:
- 如果中间只隔一个
<label>,且你只想控制紧随其后的那个<ul class="dropdown">,用input:checked + label + .dropdown - 如果中间可能插入说明文字、图标或其他元素(真实项目常见),必须用
input:checked ~ .dropdown——~匹配之后所有同级兄弟,容错性高 - 绝对不能写成
input:checked .dropdown(后代选择器)或input:checked > .dropdown(子选择器),它们对下拉菜单无效
下拉内容初始状态与动画兼容性
直接用 display: none → display: block 切换,会导致 transition 在 height 上失效,且屏幕阅读器无法感知内容变化。
立即学习“前端免费学习笔记(深入)”;
- 初始状态建议:
visibility: hidden; height: 0; overflow: hidden; opacity: 0; - 激活状态:
visibility: visible; height: auto; opacity: 1; - 过渡只加在
opacity或transform上(例如transform: translateY(-10px)),height: auto本身不可过渡 - 若需高度动画,得用 JS 或 CSS 自定义属性配合
max-height估算值(如max-height: 0→max-height: 300px),但有精度风险
最容易被忽略的是 name 属性——虽然下拉菜单一般只用单个 checkbox,但如果误写成 type="radio" 却漏了 name,或把多个 radio 的 name 拼错,整个切换就静默失败;而这种错误在 DevTools 里看不出任何异常,只能靠逐行核对 DOM 结构和属性值。


















