details+summary是HTML5原生折叠组件,语义清晰、键盘/无障碍友好;需满足summary为首个子元素且默认收起,open属性可设默认展开,支持SEO但不自动滚动或动态加载。

用 details + summary 实现原生折叠展开
直接用 HTML5 原生标签,不写 JS 就能搞定,还自带语义、键盘支持和无障碍读取。别再手写 display: none 或自己监听 click 了——既难维护,又容易在 Safari 或安卓 WebView 里失效。
关键约束只有两条:summary 必须是 details 的第一个子元素;details 默认收起,加 open 属性可默认展开:
<details>
<summary>商品参数(点击展开)</summary>
<ul>
<li>处理器:A17 Pro</li>
<li>电池容量:4500mAh</li>
</ul>
</details>
- 内容始终在 DOM 中,SEO 友好,搜索引擎能抓取
- 支持键盘 Enter/Space 触发,读屏器识别
aria-expanded状态 - 移动端点击区域包含
summary内所有空白,无需额外 padding 修复 - 若内容含
iframe、video或表单控件,展开时可能不自动加载或失焦——这时得换 JS 方案,并手动补aria-expanded和aria-controls
自定义箭头但别破坏可访问性
浏览器默认的三角标记(summary::marker)可以改,但不能删或覆盖整个 summary,否则屏幕阅读器无法感知状态变化。
推荐写法:
立即学习“前端免费学习笔记(深入)”;
summary::marker {
content: "▶ ";
}
details[open] summary::marker {
content: "▼ ";
}
- 别用
summary::-webkit-details-marker隐藏再伪元素重绘——它在 Firefox 不生效 - 想加过渡动画?只能对
details[open] > *用max-height+overflow控制,不能直接给details设height动画(不支持) - 避免
pointer-events: none或父层z-index遮挡,确保summary是可点击的最上层元素
哪些情况不能用 details?
不是所有“看起来要折叠”的地方都适合它。以下场景会直接导致行为异常或体验断裂:
- 需要滚动到展开区域顶部(
details不自动 scroll) - URL hash 同步,比如访问
#spec时自动展开参数区 - 必须兼容 IE 或 Android 4.x WebView(它们完全不支持
details) - 内容需动态加载(如点击后才 fetch 参数表),
details本身不提供加载钩子
真要 JS 版,别从零写 show/hide,优先调用 element.toggleAttribute('open') 模拟原生行为,并同步更新 aria-expanded——否则键盘用户一卡到底。
移动端点不到或连点才生效?先查这三处
这不是 details 的锅,而是常见布局干扰:
-
summary被父容器的overflow: hidden截断,实际可点击区域变小 - 外层有
transform或will-change导致合成层错位,点击坐标偏移 - 按钮嵌套在
form里,没e.preventDefault(),点一下先提交了表单
最稳的排查方式:临时加 outline: 2px solid red 到 summary,看焦点是否能正常进入。如果不能,问题一定出在层级或事件拦截上,而不是标签本身。



















