details标签原生支持折叠展开,但需summary为首个子元素且无JS即可用;实现手风琴效果须监听toggle事件并移除其他项open属性;动画需用max-height配合scrollHeight动态计算。

details 标签开箱即用,不用写 JS 就能折叠展开,但默认允许多开、没动画、不自动互斥——别指望它点一个关其他。
用 details 实现基础折叠(零 JS)
这是 HTML5 原生方案,语义正确、键盘可用、屏幕阅读器友好,现代浏览器(Chrome 12+、Firefox 49+、Safari 6.1+、Edge 79+)都支持。
常见错误现象:details 里没放 summary,或 summary 不是第一个子元素,结果点击完全没反应。
-
summary必须紧贴details开头,不能被div或换行包裹 - 默认收起;加
open属性可默认展开:<details open></details> - Safari 15.4+ 才修复
summary的 focus 样式 bug,旧版可能失焦 - 原生无 height 动画,
transition: height无效,别试
让多个 details 单开(JS 控制互斥)
想实现“手风琴”效果(点一个、其他关),必须监听 toggle 事件——它响应鼠标点击、空格键、回车键,click 会漏掉键盘操作。
核心逻辑:只在当前项 open === true 时,遍历同组所有 details,对非当前项调用 .removeAttribute('open')(不是 .open = false,后者会再触发一次 toggle)。
立即学习“前端免费学习笔记(深入)”;
实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。
- 给所有面板加统一 class,比如
class="accordion-item",方便document.querySelectorAll('.accordion-item') - 动态插入的新
details需重新绑定,或改用事件委托(监听父容器上的toggle) - 别在
summary里嵌套button或链接——点击会冒泡触发折叠;要么加event.stopPropagation(),要么把按钮移到summary外、details内
加平滑动画:用 max-height + scrollHeight 模拟
因为 height: auto 无法过渡,只能绕过 details,改用 div + max-height + transition。
关键陷阱:max-height: 500px 这种固定值容易截断长内容,或让短内容动画拖沓。
- 展开前读取目标元素的
scrollHeight,设为max-height - 收起时设
max-height: 0,同时确保overflow: hidden始终存在 - 如果内容含
padding或margin,需在 JS 中一并计入,否则动画结束时布局跳变
纯 CSS 方案:用 checkbox + :checked 控制显隐
适合需要一键全局开关(如侧边栏)、状态要持久(刷新不丢失)、且不想依赖 JS 的场景。
最稳写法:input[type="checkbox"] 必须放在 DOM 最前,紧挨着它的 label,后面紧跟所有目标元素;用兄弟选择器 :checked ~ .target 控制显隐。
- 不能隔标签、不能有换行或空格(HTML 空白符会被解析为文本节点,打断兄弟关系)
- 折叠时用
display: none,不是visibility: hidden或opacity: 0(后者仍占布局空间、Tab 键还能聚焦) - 被隐藏的元素必须同步设
tabindex="-1"和aria-hidden="true" - 移动端小屏下,建议用
@media (max-width: 768px)强制收起子级菜单,避免横向滚动
toggle 事件监听、scrollHeight 动态测高、兄弟选择器的 DOM 顺序——这三个地方出错,动画就卡,键盘就失焦,用户就皱眉。


















