纯css手风琴必须用checkbox而非radio或button,因radio互斥、button无:checked状态;需input紧邻label和content,用:checked+label+.content或:checked~.content控制,配合max-height过渡实现动画。

能实现,但必须用 关键在于 DOM 顺序:每个 纯 CSS 手风琴在真实项目里常因可访问性差被拒——尤其 iOS Safari 对 真正难的不是写出第一版,而是处理 <input type="checkbox"> 配合 <label></label> 和相邻兄弟选择器,不能只靠 <details></details> 或纯 <div>。
<h3>为什么必须用 <code>checkbox 而不是 radio 或 button
:checked 只对 <input type="checkbox"> 和 <input type="radio"> 有效,但手风琴通常需要单开单关(非互斥),radio 会强制关闭其他项,不符合交互直觉。而 button 没有 :checked 状态,无法触发伪类。
checkbox 可独立控制每项展开/收起,无需 JS 状态管理<input> 放在每组内容之前(或之后,但需调整选择器),否则无法用 ~ 或 + 选中后续元素<input> 时别用 display: none —— 它会让 :checked 失效;改用 position: absolute; opacity: 0; pointer-events: none;
如何用
~ 和 + 精确控制展开区域<input> 必须紧邻其对应标题和内容,且内容块要能被该 <input> 通过 CSS 选择器捕获。常见结构是:<input> → <label></label>(作为点击区)→ <div class="content">。
<ul>
<li>用 <code>input:checked + label + .content 可以选中「紧接在 label 后面的 content」
input:checked ~ .content,但注意它会匹配所有后续同类元素,需加 class 限定范围max-height + overflow: hidden,别用 height: auto —— CSS 无法过渡到 autoinput:checked ~ .content { max-height: 300px; opacity: 1; },对应初始状态设 max-height: 0; opacity: 0; overflow: hidden;
移动端点击区域小、焦点不可见?这些细节决定体验
label 绑定 for 的支持不稳定,且默认无 focus 样式。
<input> 有唯一 id,对应 <label for="xxx"></label>,不要只靠包裹关系(部分旧浏览器不支持)label 加 cursor: pointer 和 user-select: none,避免误选文字input:focus + label 样式,例如加 outline 或背景微调transition: max-height 0.25s ease-in-out, opacity 0.25s ease-in-out
max-height 高度不确定时的动画抖动、IE11 下 ~ 选择器兼容性、以及屏幕阅读器对隐藏 input 的播报逻辑 —— 这些没法靠一个 :checked 解决。











