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

details 和 summary 是 HTML 原生支持折叠展开的唯一语义化方案,不用 JS、不写 CSS 就能跑通,键盘可访问、屏幕阅读器识别、全现代浏览器支持——但必须严格满足结构约束,否则直接失效。
为什么details点击没反应?
最常见原因是 summary 不是 details 的第一个子元素。比如中间插了空格、注释或 <p></p>,浏览器就拒绝激活折叠逻辑。
- 错误写法:
<details><p></p> <summary>标题</summary><p>内容</p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/xiazai/skill10828" title="财经HTML高端海报生成"><img src="https://img.php.cn/upload/skill/000/000/081/179336525482166.jpg" alt="财经HTML高端海报生成" ></a> <div class="aritcle_card_info flexColumn"> <a href="/xiazai/skill10828" title="财经HTML高端海报生成">财经HTML高端海报生成</a> <p>复杂得财经如何变成清晰,适合手机看的海报?如何加上你的IP</p> </div> <a href="/xiazai/skill10828" title="财经HTML高端海报生成" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div> <p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p></details> - 正确写法:
<details><summary>标题</summary><p>内容</p> <p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p></details>(summary必须紧贴details开始) - 若需视觉留白,用 CSS
margin或padding,别加空标签或换行符 - Safari 旧版本对
open属性的 JS 修改有延迟,不要依赖details.open = true后立刻读取状态
怎么默认展开某张卡片?
加 open 属性就行,但注意它只控制初始状态,不影响后续交互逻辑。
- 静态默认展开:
<details open><summary>FAQ</summary><p>答案</p></details> - 动态默认展开(如根据 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会导致小内容“弹跳”,必须动态读取
真正容易被忽略的是:折叠内容里的 <input>、<a></a> 在收起状态下仍存在于 DOM 中,键盘 Tab 依然能访问到——这不是 bug,是规范行为。如果业务上要求“完全移除焦点流”,就必须用 JS 控制渲染,而不是仅靠 details 隐藏。


















