+可免js实现折叠,但需确保为首个子元素、兼容旧版safari用setattribute、规避webview异常、避免overflow裁剪、禁用嵌套可点击元素及pointer-events:none,并通过css重置marker与max-height过渡实现自定义动效。

直接用 <details></details> + <summary></summary> 就能实现,不需要写 JS,但必须注意 DOM 结构和浏览器兼容边界。
为什么 <details></details> 有时点不动
不是代码写错了,而是触发条件被悄悄破坏了:
-
<summary></summary>必须是<details></details>的第一个子元素,中间插个<div> 或注释都会让折叠失效 <li>Safari 15.4 之前不响应 <code>el.open = true这类 JS 赋值,setAttribute('open', '')才可靠 - 微信、QQ 内置 WebView(尤其安卓旧版)可能始终展开或完全无响应,真机测试不能跳过
- 父容器设了
overflow: hidden且高度固定,展开内容会被直接裁掉——这不是 bug,是 CSS 规则生效了 - 别嵌套
<button></button>、<a></a>或其他可点击元素,它们会吞掉 click 事件,<details></details>就收不到 - 图标建议用内联
<svg></svg>,避免图片加载失败留白;若用字体图标,确保font-display: swap -
display: flex可以用,但别给子元素设margin或align-self,容易让点击热区偏移 - 绝对禁止
pointer-events: none——哪怕只加在图标上,整个<summary></summary>就变“不可点” - 清除默认:
details summary::marker { content: ""; }(Chrome/Firefox 有效;Safari 需额外加summary::-webkit-details-marker { display: none; }) - 自定义图标:
details[open] summary::after { content: "▲"; },用 Unicode 或 SVG data URI - 高度过渡必须作用于内容区,不是
<details></details>本身:details[open] > *:not(summary) { max-height: 500px; transition: max-height 0.3s ease-out; } - 别对
<summary></summary>用transform: scale(),某些 Safari 版本会丢失热区 - 初始状态由 URL 参数决定,比如访问
?faq=2时自动展开第 2 项 - 与其他组件联动,例如导航菜单点击后同步展开对应
<details></details>
<summary></summary> 里能放什么、不能放什么
它支持内联内容,但交互敏感点很多:
怎么让箭头和过渡看起来像自己写的
原生箭头不能直接改,得先清再画:
什么时候非得用 JS 控制 open 状态
只有两种真实需求值得介入:
别为“更顺滑的动画”强行 JS 控制——height 无法从 auto 过渡,硬加只会抖动,还破坏键盘操作和读屏支持。监听 toggle 事件,不是 click,因为用户可能用空格或回车触发。











