原生+无需JS即可实现语义化、可访问的折叠效果;必须为首个直接子元素,否则点击无响应;支持键盘操作与屏幕阅读器,但动画、多组联动及旧版Safari兼容需CSS或JS补足。

原生 + 是最轻量、语义正确、可访问性最好的方案,不需要 JS 就能工作;但想加动画、控制多组联动、或兼容老 Safari,就得绕开默认行为,用 CSS 或 JS 补足。
为什么直接写 内容
没反应
内容
因为 必须是 的**第一个直接子元素**,中间不能有换行、空格或其它标签。浏览器会忽略非法结构,导致点击无响应。
怎么让 看起来像按钮又不翻车
别用 display: block 覆盖默认 display: list-item,也别用 appearance: none 或 list-style: none 粗暴清空——这会让屏幕阅读器丢失状态,键盘用户无法聚焦。
- 隐藏原生箭头:用
summary::marker { content: ""; },再补自定义图标(如summary::before) - 旋转动画要生效:给
summary::before加transition: transform 0.2s,再用details[open] summary::before { transform: rotate(90deg); } - 确保
tabindex可达:不要设pointer-events: none,也不要移除的原生焦点样式 - 需要“禁用”某处折叠?别加
disabled(无效),而是移除,或用 JS 阻止toggle事件
Safari ≤15.4 中 details.open = true 不生效怎么办
这个版本的 Safari 对 JS 动态设置 open 属性支持极差:DOM 上已标记 open,但视觉仍收起。不是代码写错,是浏览器 Bug。
- 初始化就展开?直接在 HTML 写
,别依赖 JS - 运行时切换?优先用
details.toggle()方法,它比赋值open更可靠 - 仍卡住?在
DOMContentLoaded后读一次details.offsetHeight强制重排,再调用toggle() - 监听用户操作?只监听
toggle事件(它只在用户触发后派发),别监听click或属性变更
想要高度过渡动画,max-height 为什么总出问题
原生 不支持 height 过渡,而 max-height 是常见替代方案——但它必须设具体数值,设小了截断文字,设大了动画拖沓,且内容动态加载时高度不可预知。
- 安全做法:预估最大高度(比如最多 6 行 × 行高 ≈ 300px),设
max-height: 300px,收起时设为0并加overflow: hidden - 动态内容?先设
max-height: 0,再读element.scrollHeight,然后设max-height: ${scrollHeight}px - 图片加载中?等
img.onload触发后再执行高度测量,否则scrollHeight为 0 - 更干净的选择:放弃高度动画,只用
opacity和transform: scaleY(),视觉连贯且无需测量
真正难的不是写出折叠效果,而是保证它在键盘导航下不跳失、在屏幕阅读器里有状态播报、在图片加载完成前不闪动、在 Safari 旧版里不静默失败——这些细节不处理,用户一上手就卡住。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











