优先使用details/summary实现折叠,因其语义化、自带ARIA属性和键盘支持;禁用display:none,改用hidden或visibility:hidden;需手风琴、高度动画等时才用JS+CSS方案。

HTML 本身没有原生的“折叠/展开”行为,details 和 summary 是唯一语义化支持该交互的原生组合,其他所有“折叠收起”都依赖 CSS 或 JavaScript 控制显隐。
为什么直接用 display: none 切换不推荐?
看似简单,但会破坏可访问性(屏幕阅读器无法感知状态变化)、丢失过渡动画、且无法响应 details 的原生事件(如 toggle)。更关键的是:没有语义,搜索引擎和辅助技术无法理解这是可交互的折叠区域。
实操建议:
- 优先用
details/summary实现基础折叠,它自带 ARIA 属性(aria-expanded自动管理)和键盘支持(空格/回车触发) - 若需自定义样式(比如去掉默认箭头、改字体、加图标),用
summary::marker { content: "" }清除,再用伪元素或svg替代 - 避免对
details直接设display: none—— 这会让整个区块不可见且不可交互,应改用hidden属性或visibility: hidden
details 的兼容性和可控性边界在哪?
Chrome 12+、Firefox 49+、Safari 6.2+、Edge 79+ 支持完整功能;iOS Safari 从 iOS 10.3 开始支持。但注意两个硬限制:
立即学习“前端免费学习笔记(深入)”;
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
-
details不支持嵌套(子details在部分旧 Safari 中会失效) - 无法通过 CSS 选择器精确捕获“已展开”状态做复杂样式联动(比如兄弟元素随展开变色),只能靠
details[open]伪类,且仅限直系样式 - 若需监听展开/收起动作,必须用 JS 监听
toggle事件,而非click—— 后者在键盘操作时不会触发
示例:
<details>
<summary>点击展开</summary>
<p>这里是折叠内容</p>
</details>
<p><script>
document.querySelector('details').addEventListener('toggle', (e) => {
console.log('当前状态:', e.target.open); // true=展开,false=收起
});
</script>
什么时候必须放弃 details,改用 JS + CSS?
当需要以下任一能力时:details 就不够用了:
- 多个折叠面板互斥(手风琴效果),
details默认各自独立 - 内容区域有高度过渡动画(
details内部元素不能直接用transition: height,因为高度是自动计算的) - 服务端渲染中需初始状态为“展开”,但又不想暴露全部 HTML 内容(
details加open属性即展开,内容仍存在于 DOM 中) - 需要配合 Vue/React 等框架的状态驱动,而原生
details的open属性不是双向绑定的
此时推荐最小化 JS 方案:用 aria-expanded + aria-controls 手动管理,配合 max-height 过渡或 height: auto 的 JS 测量(避免硬编码像素值)。
真正容易被忽略的是:折叠组件是否在打印样式中保留可读性?details[open] 在 @media print 下默认仍折叠,需额外写 details { display: block } details > * { display: block } 才能确保打印时内容可见。


















