只能用:checked,因:hover松开即失效、:active仅瞬时触发,唯:checked能持久记录点击状态;必须满足input与内容同父、相邻、label正确绑定三大结构约束,且用max-height而非height实现过渡。

纯 CSS 实现点击展开/折叠面板,:checked 是唯一可靠且无需 JS 的状态锚点;但必须严格满足 DOM 位置与结构约束,否则样式完全不生效。
为什么只能用 :checked,不能用 :hover 或 :active
:hover 依赖光标悬停,松开即收起;:active 只在鼠标按下瞬间触发,无法维持状态。只有 :checked 能真实记录“已点击”这个持久化布尔状态——前提是它绑定的是 <input type="checkbox"> 或 <input type="radio">。
-
<input type="checkbox">适合单个独立面板(可多开) -
<input type="radio">适合手风琴模式(互斥单开),需共用name属性 - 绝对不能用
<button></button>或<div> 替代 <code>input,它们没有:checked状态:checked+ 兄弟选择器生效的三个硬性条件哪怕 HTML 多一个包裹层、少一个换行,
:checked + .panel或:checked ~ .panel都会失效。-
<input>必须和目标内容元素(如<div class="panel-content">)处于**同一父容器内**,且是它的**前序兄弟节点** <li> <code><label></label>必须用for属性精确绑定<input>的id,不能靠嵌套:<label><input><div></div></label>是无效结构 -
<input>不能被display: none移出文档流;可用position: absolute; opacity: 0; pointer-events: none;隐藏但保留可交互性 - 给内容区设
max-height: 0; overflow: hidden;(收起态) - 在
input:checked ~ .panel-content中设max-height: 500px;(足够覆盖最大内容高度) - 同时加
transition: max-height 0.3s ease, opacity 0.2s ease;,再配合opacity提升感知流畅度 - 避免用
display: none/block切换,它会中断所有过渡动画
如何写过渡动画才不会卡顿或闪跳
直接对
height做transition无效,因为height: auto无法参与 CSS 过渡。必须用max-height模拟。立即学习“前端免费学习笔记(深入)”;
细节上最容易被忽略的兼容性陷阱
IE11 支持
:checked和~,但不支持max-height过渡的「自动高度」模拟——500px 这个值必须手动预估,超了会截断,小了会撑不开。移动端 Safari 对max-height过渡的渲染有时有延迟,建议加will-change: max-height;提示合成层。如果内容高度差异极大,或需要真正响应式伸缩,
details/summary是更稳妥的语义化替代方案,但它不支持手风琴逻辑(除非加少量 JS 控制open属性)。纯 CSS 的边界就在这里:结构可控、高度可预估,才能稳住。 -


















