details标签需有且仅有一个summary作为首子元素,否则无折叠功能;summary默认内联,用::marker替换三角图标最稳;open属性控制状态,toggle事件监听变更;非手风琴组件,复杂交互应选aria方案。

details 标签不展开?检查是否漏了 summary
没写 <summary>,<details> 就不会渲染折叠控件,点不动、看不见箭头、也不响应点击——浏览器直接当普通块级元素处理,连默认样式都不加。
必须有且仅有一个 <summary> 作为 <details> 的第一个子元素,否则折叠逻辑失效。其他内容(包括空格、换行)如果出现在 <summary> 前,也会导致解析失败。
-
<details><summary>标题</summary>正文</details>✅ 正常 -
<details><p>说明</p><summary>标题</summary></details>❌ 不折叠 -
<details>正文</details>❌ 完全无交互
summary 里放图标或文字,怎么对齐才不跳动
默认情况下,<summary> 自带一个向右的三角形(open 状态变向下),但这个图标是内联的、不可选中、不占布局空间;一旦你用 CSS 给它加 display: block 或浮动,图标就容易错位甚至消失。
最稳的做法是保留 <summary> 的默认 display(inline),只通过 padding-left 或伪元素补图标:
<details>
<summary>配置项</summary>
<p>这里是详细说明...</p>
</details>
<p><style>
summary::marker { content: "▶ "; } /<em> 替换默认三角 </em>/
summary[open]::marker { content: "▼ "; }
</style>- 避免对
<summary>设display: flex或text-align: center,会干扰原生行为 - 不要用
font-size: 0隐藏原生 marker 再重绘—— Safari 旧版不支持::marker - 如果需兼容 IE(已淘汰),只能放弃
<details>,改用 JS 模拟
JavaScript 控制展开状态:open 属性和事件监听
<details> 的展开/收起由 open 属性控制,它是可读写的布尔属性,不是 class 或 data-*。直接操作 DOM 节点比监听 click 更可靠。
- 展开:
el.open = true(触发toggle事件) - 收起:
el.open = false - 监听变化:
el.addEventListener('toggle', () => console.log(el.open)) - 注意:
click事件在<summary>上触发,但无法区分用户点击和脚本设置;toggle才是真实状态变更信号
常见误用:el.setAttribute('open', '') 虽然能展开,但后续 el.open 读出来仍是 false(属性 vs 属性值),造成状态不一致。
兼容性和语义陷阱:别把它当“手风琴组件”用
<details> 是语义化标签,代表“可选查看的附加信息”,不是 UI 组件。它的默认行为(键盘支持、屏幕阅读器播报)很好,但扩展性差:
- 不支持多开(除非手动管理多个
open属性) - 不能嵌套
<details>实现二级折叠(部分浏览器会中断事件冒泡) - Chrome/Firefox 支持
open属性初始值,但 Safari 对<details open>的 SSR 渲染偶尔延迟一帧 - 如果需要动画过渡,得自己加 CSS(
max-height+transition),原生不带动画
真正要写手风琴、侧边栏菜单、FAQ 列表,优先考虑 <button aria-expanded> + aria-controls 组合,可控性更强,也更符合无障碍规范。

















