用和最快实现折叠面板无需JS或CSS框架,原生支持语义化、无障碍及键盘操作;兼容Chrome 12+、Firefox 49+、Safari 6+、Edge 79+及iOS Safari 10.3+;自定义箭头应使用list-style: none配合::before添加图标,保留tabindex和焦点样式,避免破坏可访问性。

用 details 和 summary 最快实现折叠面板
不用写 JS,不用引 CSS 框架,原生 HTML 就能做可点击展开/收起的商品介绍面板——details 是语义化、无障碍、默认支持键盘操作的正确选择。
浏览器兼容性没问题:Chrome 12+、Firefox 49+、Safari 6+、Edge 79+ 都支持;iOS Safari 从 iOS 10.3 开始也 OK。
常见错误是强行用 div + onclick + display: none 模拟,结果无法键盘聚焦、屏幕阅读器读不出状态、移动端点按反馈差。
<details><summary>? 商品详情</summary><p>材质:100% 再生棉</p> <p>尺寸:M / L / XL(见尺码表)</p> <p>洗涤建议:冷水机洗,勿漂白</p> </details>
怎么自定义箭头和样式不破坏语义
summary 默认带一个下拉小三角,但多数商品页需要隐藏它,换成图标或文字提示。关键点:不能用 display: none 直接干掉 summary::marker,否则部分屏幕阅读器会丢失“可展开”提示。
- 用
list-style: none清除默认标记,再用::before加自定义图标(如▶或 SVG) - 必须保留
summary的tabindex和原生 focus 样式,否则键盘用户无法操作 - 展开时
details[open]伪类可用,比如加个底边框:details[open] { border-bottom: 1px solid #eee; }
别在 summary 里塞 button —— 会导致双倍按钮语义,AT(辅助技术)可能报错。
为什么不要用 JS 手动控制 open 属性
直接改 details.open = true 看似可控,但容易踩三个坑:
- 手动触发后,
toggle事件不会自动派发,监听toggle做动画或埋点就失效 - 如果多个
details要互斥(单选展开),JS 控制逻辑易出竞态,而用details原生行为 + CSS:not([open])更稳 - 服务端渲染(SSR)场景下,初始
open状态若靠 JS 注入,首屏会闪一下空白再展开,体验差
真要默认展开?直接写 即可,浏览器原生处理,无 JS 依赖。
移动端点按区域太小怎么办
默认 summary 只有文字区域响应点击,手指点不准容易失败。解决方法不是加 JS,而是扩大可点击范围:
- 给
summary设padding(比如padding: 12px 16px),别只靠 margin - 用
min-height+display: flex+align-items: center垂直居中,避免文字贴顶 - 避免在
summary外层再套一层div并绑定 click —— 会干扰原生焦点流和语义树
复杂交互(比如点击标题外区域也收起)确实需要 JS,但纯商品介绍面板,原生 details 已经覆盖 95% 场景,过度封装反而增加维护成本和兼容风险。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











