details 和 summary 是 HTML 唯一原生支持折叠展开的语义化方案,但必须确保 summary 为 details 的首个子元素,否则失效;open 属性控制默认展开,::marker 兼容性差需用 ::before 替代,原生不支持 height 过渡,动态高度需 JS 计算 scrollHeight。

details 和 summary 是 HTML 原生支持折叠展开的唯一语义化方案,不用 JS、不写 CSS 就能跑通,键盘可访问、屏幕阅读器识别、全现代浏览器支持——但必须严格满足结构约束,否则直接失效。
为什么details点击没反应?
最常见原因是 summary 不是 details 的第一个子元素。比如中间插了空格、注释或 ,浏览器就拒绝激活折叠逻辑。
- 错误写法:
标题
内容
- 正确写法:
(标题
内容
summary必须紧贴details开始) - 若需视觉留白,用 CSS
margin或padding,别加空标签或换行符 - Safari 旧版本对
open属性的 JS 修改有延迟,不要依赖details.open = true后立刻读取状态
怎么默认展开某张卡片?
加 open 属性就行,但注意它只控制初始状态,不影响后续交互逻辑。
- 静态默认展开:
FAQ
答案
- 动态默认展开(如根据 URL 参数):
document.querySelector('[data-id="faq-2"]').open = true - 别用
setAttribute('open', '')—— 这会把值设为字符串,而原生属性是布尔型,应直接赋值true/false - 批量操作时只改
open,不要删 DOM 或切 class:document.querySelectorAll('details').forEach(d => d.open = true)
想加旋转箭头动画,::marker 为啥不生效?
::marker 在 Safari 15.4 之前基本不可用,Chrome/Firefox 支持较好,但不能单独靠它做跨浏览器方案。
- 安全做法:先用
summary { list-style: none; }清掉默认样式 - 再用
summary::before补图标:content: "▶"; transition: transform 0.2s; - 展开时旋转:
details[open] summary::before { transform: rotate(90deg); } - 别给
summary设display: block—— 它会失去按钮语义,键盘无法聚焦 - 如果内容含图片或异步加载,
scrollHeight可能读不准,得等load或resize后再测
需要滑动动画,还能用details吗?
不能。原生 details 不支持 height 或 max-height 过渡,强行加 transition 无效或抖动。要动画就得放弃它的内置行为,改用 JS + max-height 方案。
- 核心限制:CSS 过渡不支持
height: auto,所以目标值必须是具体数字(如500px)或scrollHeight - 动态高度更准:
el.style.maxHeight = el.scrollHeight + 'px',但得在样式重置后强制重排(如读el.offsetHeight) - 收起后建议清空
max-height行内样式(设为''),否则后续 JS 计算scrollHeight可能被干扰 - 若文档里有大量折叠项,且内容高度差异大(20px vs 1200px),固定写死
max-height: 600px会导致小内容“弹跳”,必须动态读取
真正容易被忽略的是:折叠内容里的 、 在收起状态下仍存在于 DOM 中,键盘 Tab 依然能访问到——这不是 bug,是规范行为。如果业务上要求“完全移除焦点流”,就必须用 JS 控制渲染,而不是仅靠 details 隐藏。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











