原生 <details> 和 <summary> 标签可零 JS 实现语义化手风琴效果,支持无障碍、键盘操作及默认收起/展开;通过 max-height 过渡可添加动画,现代浏览器广泛支持,IE 需降级处理。

用 <details> 和 <summary> 最快实现手风琴效果
现代浏览器原生支持手风琴折叠,根本不用写 JS 或引入库。只要用好 <details> 和 <summary> 这对语义化标签,就能直接生效。
它们默认就是点击展开/收起,且自带 ARIA 属性,无障碍友好。注意:<details> 默认是收起状态,加 open 属性可让它初始展开。
<details> <summary>常见问题</summary> <p>这里是折叠内容,可以放任意 HTML 元素。</p> </details>
为什么不用 display: none + JS 手动控制
自己用 CSS 隐藏 + JS 切换 display 看似灵活,但容易漏掉几个关键点:
- 没处理键盘操作(比如按回车或空格键触发展开)
- 没同步更新
aria-expanded和aria-controls,屏幕阅读器无法识别状态 - 动画过渡需要额外写 CSS(
<details>本身不带动画,但可配合max-height+transition补上) - 多个折叠项共存时,手动管理“互斥展开”逻辑容易出错(而原生
<details>天然独立)
给 <details> 加平滑展开动画
<details> 本身没有 CSS 动画接口,但可以用 max-height 模拟过渡效果。关键是:不能用 height: auto 做过渡(无效),得设一个足够大的固定值。
立即学习“前端免费学习笔记(深入)”;
示例 CSS:
details[open] summary ~ * {
animation: sweep 0.3s ease-in-out;
}
@keyframes sweep {
0% { opacity: 0; max-height: 0; }
100% { opacity: 1; max-height: 500px; }
}注意:500px 要大于你所有可能内容的高度;如果内容高度差异大,这个值设太小会截断,设太大则收起时有延迟感。
兼容性与降级处理要点
<details> 在 Chrome 12+、Firefox 49+、Safari 6.2+、Edge 79+ 中都可用。IE 完全不支持——如果你必须兼容 IE,就别用它,老实用 JS 方案。
若只需轻微降级(比如让内容始终可见),可这样写:
details {
display: block;
}
details > summary {
cursor: pointer;
}
/* IE 下 details 不识别,会把内部所有内容当普通块级元素渲染 */
更稳妥的渐进增强做法是:先确保所有 <summary> 后的内容在无 JS/无 <details> 时仍可读,再用 JS 检测支持性并封装交互逻辑——但绝大多数现代项目,直接用原生标签就够了。
真正要注意的是:别在 <summary> 里放交互元素(比如按钮、链接),否则点击行为可能冲突;如果必须放,得用 pointer-events: none 控制事件穿透,再单独绑定事件。



















