details 和 summary 是浏览器原生支持的折叠组件,无需 JS 即可实现点击展开/收起,语义化强、无障碍友好;summary 必须为 details 的首个子元素,通过 ::marker 自定义箭头,用 [open] 控制展开样式。

用 details 和 summary 最快实现点击展开收起
浏览器原生支持,不用 JS、不引库、零学习成本。只要两个语义化标签嵌套,就能做出可点击切换的折叠区域。
常见错误是手动写 onclick + display: none 切换,既冗余又破坏可访问性。而 details 是专门为这个场景设计的 HTML 元素,自带 ARIA 属性和键盘支持(空格/回车都能触发)。
-
details是容器,初始默认收起;加open属性可默认展开 -
summary必须是details的第一个子元素,它就是那个可点击的标题栏 - 里面可以放任意 HTML 内容(
p、ul、甚至iframe),不限文本
点我展开
这里是被隐藏的内容,可以很长。
console.log("hello");想自定义样式?重点改
summary::marker和details[open]浏览器默认会在
summary前加一个三角箭头,但这个箭头不是文字也不是伪元素,而是::marker—— 很多人卡在这儿,以为用::before就能覆盖,结果无效。立即学习“前端免费学习笔记(深入)”;
另外,
details展开时会带[open]属性,这是你控制内部样式的关键钩子,比如让展开后背景变浅、加边框等。
- 去掉默认箭头:
summary::marker { content: ""; }- 加自定义图标(用字体或 SVG):
summary::after { content: "▶"; },再配合details[open] summary::after { content: "▼"; }- 展开时给内容区加过渡动画?不行——
details不支持height过渡,因为高度是自动计算的。真要动效得用 JS 配合max-heightIE 和旧版 Safari 不支持?那就用
aria-expanded+ 简单 JS 回退
details在 IE 全系、Safari ≤ 11.1 中完全不可用。如果项目必须兼容这些环境,不能硬上,得降级。核心思路:检测是否支持
details,不支持就用div模拟,手动管理aria-expanded和hidden属性,保持语义和键盘可用性。
- 检测方式:
"open" in document.createElement("details")- JS 只需监听
summary点击,然后切换hidden属性和aria-expanded值- 别忘了给
summary加tabindex="0",否则键盘用户点不到- CSS 回退规则里,对不支持的环境用
.no-details summary + * { display: none; }控制隐藏别把
details当 Accordion 用(多个联动)原生
details是独立开关,彼此不干扰。如果你需要“一次只展开一个”,比如 FAQ 折叠面板,就得自己加逻辑控制 —— 浏览器不会帮你关掉别的details。容易踩的坑是直接在
summary上绑click,然后遍历所有兄弟details设open = false,结果发现:用户用键盘打开后,再按 Tab 切到下一个summary,前一个没自动关闭,体验断裂。
- 正确做法:监听
toggle事件(details原生事件),再统一处理其他项- 或者更稳一点:用 JS 实现整个 Accordion,把
details当纯样式占位,逻辑全由 JS 掌控- 移动端双击缩放问题?某些 iOS 版本下快速连点可能触发缩放,加
viewport的user-scalable=no不推荐,改用touch-action: manipulation更精准真正麻烦的从来不是怎么展开,而是怎么让展开后的内容不撑破布局、不打断屏幕阅读器节奏、不和第三方组件打架。这些细节没试过几遍根本想不到。











