点击无反应最常见原因是未作为其首个子元素;需用max-height+JS实现高度动画;多级互斥需监听toggle事件并动态控制open属性。

直接用 <details></details> + <summary></summary> 就能实现基础折叠,无需 JS、语义正确、键盘可访问;但想加高度动画、多级联动或兼容 IE,就得换方案。
为什么<details></details>点击没反应
最常见原因是 <summary></summary> 没放在 <details></details> 的第一个子位置。浏览器只认「首个子元素是 <summary></summary>」这个结构,否则不绑定折叠逻辑。
- 错误写法:
<details><div>说明文字</div><summary>标题</summary>...</details></li> <li>正确写法:<code><details><summary>标题</summary><p>内容</p></details></li> <li>默认收起,加 <code>open
属性即默认展开:<details open><summary>FAQ</summary>...</details></li> <li>别在 <code><summary>
上手动绑onclick—— 它本就响应空格/回车,加了反而可能干扰键盘操作
<details></details>里怎么改箭头图标
summary::marker 在 Safari 中支持极差,Chrome/Firefox 也仅部分生效,不能依赖它控制图标。
立即学习“前端免费学习笔记(深入)”;
- 统一用
summary::before插入图标,比如content: "▶" - 隐藏原生箭头必须写
summary { list-style: none; },单靠::marker { content: "" }不保险 - 旋转动画靠
transform: rotate(90deg)+transition,展开态用details[open] summary::before触发 - Safari 对
details[open]伪类匹配有时延迟,建议 JS 同时加is-open类兜底
怎么实现平滑高度展开动画
<details></details> 原生不支持 height 或 max-height 过渡 —— 浏览器内部用的是 display 切换,CSS 动画无法介入。
- 要动画,就得放弃原生行为,改用
max-height+ JS 控制:先设max-height: 0; overflow: hidden;,再通过element.scrollHeight动态读取真实高度并赋值 - 别写死
max-height: 500px—— 内容短时会“弹跳”,长时动画变慢;必须 JS 测量后设置 - 收起后记得清掉
style.maxHeight(设为''),否则后续scrollHeight判断可能出错 - 如果内容含图片或 iframe,展开后需手动触发
loading="lazy"或IntersectionObserver,否则资源不加载
多个折叠项如何互斥(手风琴效果)
原生 <details></details> 默认各自独立,没有内置互斥逻辑。
- 监听
toggle事件(不是click),它在用户手动展开/收起时触发,且兼容键盘操作 - JS 遍历同级所有
<details></details>,对非当前项调用.removeAttribute('open') - 注意不要用
display: none硬切——会影响屏幕阅读器和焦点流;优先用max-height: 0+overflow: hidden - 如果折叠内容里有表单控件,互斥切换时得手动管理
focus(),否则键盘用户会卡住



















