details 和 summary 必须成对使用,summary 必须是 details 的第一个子元素,否则点击无效;open 属性仅控制初始状态,切换需用 toggle() 方法;禁止嵌套 details,多级折叠需 JS 模拟;移动端需监听 touchstart 兼容点击。

details 和 summary 必须成对出现,不能单独用
单独写 <summary> 或只写 <details> 都不会触发交互行为——浏览器会忽略或降级渲染。必须把 <summary> 作为 <details> 的第一个子元素,否则点击无反应,控制台也不会报错,容易误以为是样式问题。
常见错误现象:
-
<summary>放在<details>外面,比如先写标题再包内容 -
<details>里塞了其他元素(如<p>)在<summary>前面 - 用了自闭合写法
<summary/>—— HTML 不支持
正确结构只有这一种:
<details> <summary>点击展开</summary> <p>这里是隐藏内容</p> </details>
open 属性控制默认展开状态,但 JS 修改需用 toggle()
open 是布尔属性,写上就展开,不写就不展开。但它只影响初始状态,后续切换必须靠用户点击或 JS 调用 toggle() 方法。直接改 element.open = true 不会触发 DOM 更新或动画,视觉上没变化。
立即学习“前端免费学习笔记(深入)”;
使用场景:
- 服务端渲染时根据业务逻辑决定默认展开(如错误提示页默认展开详情)
- 配合 JS 实现“全部展开/收起”批量操作
推荐写法(避免手动赋值):
const el = document.querySelector('details');
el.toggle(); // 切换状态,触发重绘和 transition
原生交互不支持嵌套 details,CSS 伪类才是关键扩展点
HTML 规范明确禁止 <details> 嵌套——浏览器会自动截断内层 <details>,导致结构断裂、事件丢失。想实现多级折叠,得靠 CSS + JS 模拟,而不是依赖原生嵌套。
真正可控的扩展点是伪类:
-
details[open] > summary::after可加箭头图标 -
details:not([open]) summary控制未展开时的样式 - 配合
transition: max-height .2s ease实现平滑展开(注意:需设max-height,不是height)
性能提醒:不要给 <details> 加 overflow: hidden 后再设 height: auto,这会导致 layout thrashing。
移动端 click 事件失效?别忘了 touchstart 兼容
部分 Android 浏览器(尤其旧版 WebView)对 <summary> 的 click 事件响应迟钝或完全不触发。这不是 bug,而是因为 <summary> 默认不冒泡且某些 UA 把它当非可点击区域处理。
稳妥做法是主动绑定 touchstart 并阻止默认行为:
document.querySelectorAll('summary').forEach(s => {
s.addEventListener('touchstart', e => {
e.preventDefault();
s.parentElement.toggle();
});
});
容易被忽略的地方:iOS Safari 在 <details> 里放 <input> 时,键盘弹出会意外收起面板——目前无标准解法,只能用 JS 监听 focusin 后手动 open。



















