details 元素是纯 css 实现展开/收起的最简方案,原生支持、语义正确、无障碍友好;通过 details[open] 控制显隐,用 max-height 或 clip-path 实现过渡动画,需重置默认样式并避免破坏可访问性。

用 details 和 summary 是最简方案
纯 CSS 实现「点击展开/收起」不需要 JS,浏览器原生支持的 details 元素就是为此设计的。它默认可折叠,语义正确,还自带 ARIA 属性,无障碍友好。
关键点在于:details 默认关闭,summary 是唯一可点击区域,点击后自动切换 open 属性 —— 这个属性能被 CSS 选中,用来控制子内容显隐或添加过渡效果。
-
summary::marker可以自定义小箭头(比如改成 + / −) - 想加展开动画?CSS 不能直接对
height: auto做过渡,得配合max-height或clip-path模拟(见下一条) - 注意:Safari 旧版本(≤15.4)对
details[open]的 CSS 选择器支持不一致,建议加一层details:not([open]) > *做兼容兜底
加展开收起动画必须绕开 height: auto
CSS 过渡无法作用于 height: auto,所以不能直接写 transition: height 0.3s。常见做法是用 max-height 代替,但需预估最大高度值;更稳妥的是用 clip-path 或 transform: scaleY() 配合 overflow: hidden。
- 用
max-height:设一个足够大的固定值(如max-height: 500px),再配overflow: hidden,展开时从0过渡到该值;缺点是内容超长会截断 - 用
clip-path:初始设clip-path: inset(100% 0 0 0),展开时变为clip-path: inset(0),配合transition: clip-path 0.25s ease,无高度限制 - 避免用
opacity单独做动画 —— 它不占布局空间,收起后仍会撑开父容器
details 的样式重置容易漏掉几个关键点
不同浏览器对 details 的默认样式差异不小,比如 Chrome 会给 summary 加粗、Firefox 默认有上下 margin、Safari 的 ::marker 不显示。重置时要盯住这几处:
- 清除
summary的默认加粗:summary { font-weight: normal; } - 移除
details的外边距:details { margin: 0; } - 隐藏原生 marker 后,自己加图标要用
display: flex对齐,否则文字和图标基线错位 - 移动端点击区域太小?给
summary加padding并设cursor: pointer,别只靠默认行为
需要禁用右键菜单或阻止默认行为?别动 details
有人想禁用右键、或者阻止点击穿透,就给 details 加 oncontextmenu="return false" 或监听 click 阻止事件 —— 这会破坏原生可访问性,屏幕阅读器可能无法识别展开状态。
- 右键菜单不是问题,它不影响功能,也不暴露敏感信息,没必要禁
- 如果真要拦截点击(比如嵌套了按钮),应该把交互逻辑移到子元素上,而不是覆盖
details的默认行为 - 真正要注意的是:不要用
pointer-events: none或disabled属性,它们会让整个面板不可操作且无法被辅助技术读取
clip-path 动画比 max-height 更可靠,但老设备可能掉帧;而删掉 summary 标签、只用 div 模拟,等于放弃语义和键盘导航支持 —— 这些不是“高级技巧”,是底线。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











