:checked是唯一可被用户主动触发且维持的CSS布尔状态,结合~或+兄弟选择器可纯CSS实现点击展开;需确保checkbox在DOM中位于目标前、label正确绑定、用opacity:0等隐藏而非display:none,并设初始display:none。

用 :checked 配合 sibling 选择器控制下拉显示
纯 CSS 实现点击展开,:checked 是最稳定、语义清晰的方案。核心是把 <input type="checkbox"> 放在触发按钮和下拉内容之前,用 ~(通用兄弟选择器)或 +(相邻兄弟选择器)联动显示/隐藏。
常见错误是把 checkbox 放在容器内部或顺序错乱,导致选择器失效;或者忘记设置 display: none 初始状态。
- HTML 结构必须为:
<input id="toggle">→<label for="toggle">→<ul class="dropdown"> -
.dropdown { display: none; },然后写#toggle:checked ~ .dropdown { display: block; } - 若下拉内容紧挨 checkbox,用
+更精准;若中间有 label 等元素,必须用~ - label 必须带
for="toggle"或包裹 checkbox,否则点击不触发状态切换
用 :focus-within 实现鼠标悬停+键盘焦点双支持
:focus-within 适合需要键盘可访问性的场景(比如 Tab 进入后自动展开),但它不能响应纯点击 —— 它依赖子元素获得焦点。所以得配合 tabindex 和可聚焦元素(如 <button> 或带 tabindex="0" 的 <div>)。
容易忽略的是:父容器默认不可聚焦,:focus-within 不会生效;且移动端 Safari 对 :focus-within 的 click 触发支持不稳定。
立即学习“前端免费学习笔记(深入)”;
- 给下拉容器加
tabindex="-1"不够,要确保至少一个子元素可聚焦(如<a href="#">或<button>) - 触发区域建议用
<button>而非<div>,天然可聚焦且语义正确 - 初始隐藏仍需
.dropdown { display: none; },再写.dropdown:focus-within { display: block; } - 注意与
:hover共存时的层叠逻辑::hover在桌面有效,:focus-within在键盘操作时补位
定位方式选 position: absolute 还是 position: relative?
下拉列表必须脱离文档流,否则会撑开父容器、影响布局。99% 场景该用 position: absolute,且父容器需设 position: relative 作为定位上下文。
常见坑是忘了给父容器加 position: relative,结果下拉框相对 <body> 定位,飘到页面角落;或用了 position: fixed 导致滚动时错位。
- 父容器(如
<nav>或<div class="dropdown-wrapper">)必须含position: relative - 下拉内容用
position: absolute; top: 100%; left: 0;对齐触发按钮底部 - 避免用
margin-top模拟下拉位置 —— 它不脱离文档流,会引发重排且难对齐 - 若需右对齐,改
left: auto; right: 0;,别用text-align: right
移动端点击穿透与 focus 失效问题怎么解
iOS Safari 和部分安卓浏览器中,:focus 和 :focus-within 在点击后可能瞬间获得又立刻丢失焦点,导致下拉闪退。checkbox 方案虽稳定,但默认 checkbox 本身可见,需隐藏它并确保 label 可点。
根本原因不是 CSS,而是原生表单控件行为和移动端事件机制差异。绕过它的关键是:让视觉触发区完全接管交互,且不依赖伪类“维持”状态。
- 隐藏 checkbox 必须用
position: absolute; opacity: 0; pointer-events: none;,不能只靠visibility: hidden或display: none(后者会断开 DOM 关联) - label 必须覆盖整个触发区域(可用
display: block; width: 100%),否则点击空白处不触发 - 真要兼容老 iOS(ontouchstart="" 到 label 上可强制触发 focus 流程
- 如果用 JS 做降级,只监听
click切换 class,CSS 用.dropdown.open控制显示,比强依赖伪类更可靠
:checked + ~ 是首选,干净、无 JS、可访问性好;但一旦涉及复杂交互(如点击外部收起、键盘 ESC 关闭),就得引入轻量 JS —— 纯 CSS 在边界情况下的控制力始终有限。


















