原生 <details>+<summary> 是 HTML5 语义化折叠组件,支持无 JS 展开/收起及可访问性;<summary> 必为首个子元素,加 open 属性可默认展开;兼容主流现代浏览器,但 IE 不支持;自定义箭头可用 ::before,动画需 JS 配合 max-height 实现。

DETAILS 和 SUMMARY 标签的基本用法
原生 <details> + <summary> 是 HTML5 提供的语义化折叠组件,无需 JS 就能实现点击展开/收起,且自带可访问性支持(如屏幕阅读器识别、键盘空格/回车触发)。
最简结构是:<details><summary>标题</summary>展开内容</details>。注意:<summary> 必须是 <details> 的第一个子元素,否则浏览器可能忽略或渲染异常。
默认状态下 <details> 是收起的;加 open 属性可默认展开:<details open><summary>初始展开</summary>…</details>。
为什么点击没反应?常见兼容与样式问题
IE 完全不支持 <details>,Edge 15+、Chrome 12+、Firefox 49+、Safari 6+ 支持。如果测试时无反应,先检查浏览器版本。
另一个高频问题是 CSS 干预导致交互失效:
-
<summary>默认是 display: list-item,若设了display: block或flex,可能丢失内置的“小箭头”和点击区域,但功能仍存在(只是视觉反馈消失) - 给
<summary>加pointer-events: none会彻底禁用点击 - 父容器有
overflow: hidden且<details>高度变化时,可能裁剪展开内容(需配合 max-height 动画或重置 overflow)
如何自定义箭头和展开动画?
浏览器对 <summary> 的 ::marker 伪元素支持有限(Chrome/Safari 支持,Firefox 不支持),所以稳妥做法是用 background-image 或 ::before 替换默认箭头:
summary::before {
content: "▶";
margin-right: 6px;
font-size: 0.8em;
}
details[open] summary::before {
content: "▼";
}
原生 <details> 不支持 CSS 过渡(height 无法从 0→auto 动画),要加展开动画必须用 JS 监听 toggle 事件 + 手动控制 max-height:
- 监听
details.addEventListener('toggle', ...) - 展开时:先设
max-height为 0,offsetHeight强制重排,再设目标高度(如scrollHeight) - 收起时反之,最后用 transition 监听 height 变化
纯 CSS 方案只能靠 max-height 固定值过渡(如 max-height: 0 → max-height: 300px),但内容高度不确定时易出现滚动条或截断。
与 JavaScript 交互时要注意什么?
<details> 的 open 属性是反映状态的唯一可靠来源 —— 不要用 class 判断是否展开,而应读取 element.open 布尔值。
JS 控制开关只需赋值:el.open = true 或 el.open = false,这会触发 toggle 事件,适合做联动逻辑(比如一个面板打开时自动关闭其他)。
容易被忽略的一点:toggle 事件在用户点击和 JS 赋值时都会触发,但无法区分来源。如果需要只响应用户操作,得结合 event.target === event.currentTarget 和事件委托谨慎判断。
另外,动态插入的 <details> 元素无需额外初始化,浏览器会自动接管其行为。

















