折叠面板无需js即可运行,但必须是的第一个且唯一直接子元素;open属性在部分环境失效时可用css或js修复;单开效果需js监听toggle事件;平滑动画应使用max-height而非height过渡。

直接用 <details></details> + <summary></summary> 就能在线运行出可用的折叠面板,无需 JS、不依赖任何库,复制粘贴进 HTML 编辑器(如 CodePen、JSFiddle 或浏览器开发者工具的 Elements 面板)立刻生效。
为什么<details></details>在在线编辑器里点不动
最常见原因是结构写错了:<summary></summary> 必须是 <details></details> 的**第一个且唯一直接子元素**。下面这些写法都会失效:
-
<details><div><summary>标题</summary></div> <p>内容</p></details>(<summary></summary>被<div> 包裹)<li> <code><details><h3><summary>标题</summary></h3> <p>内容</p></details>(<h3></h3>干扰了父子关系) -
<details><p><summary>标题</summary></p> <p>内容</p></details>(<p></p>是块级元素,不能作为<summary></summary>父容器) - 加 CSS 强制初始可见:
details[open] { display: block; },再配合details > * { opacity: 1; }防闪动 - 在
底部加一行 JS:document.querySelectorAll('details[open]').forEach(d => d.open = true);
正确写法只有一种:<details><summary>标题</summary><p>内容</p></details> —— 中间不能插任何标签。
在线运行时open属性不生效怎么办
部分在线环境(尤其是旧版 Safari WebView 或某些 CMS 预览模式)会忽略 open 属性。这不是你代码错,是浏览器行为差异。临时解决方法有两个:
注意:不要用 display: none 控制显隐——它破坏可访问性,键盘用户按空格/回车会无响应。
怎么让多个 FAQ 折叠项单开(手风琴效果)
<details></details> 默认各自独立,要实现“点一个、关其他”,必须加 JS。但别监听 click,改用 toggle 事件,它兼容键盘操作(空格/回车)且只在状态真正变化后触发:
document.querySelectorAll('.faq-item').forEach(item => {
item.addEventListener('toggle', e => {
if (!e.target.open) return;
document.querySelectorAll('.faq-item').forEach(other => {
if (other !== e.target) other.open = false;
});
});
});
关键点:.faq-item 是你给每个 <details></details> 加的 class;e.target.open === true 才执行关闭逻辑,避免收起时误清状态。
动画一卡一卡的,怎么平滑展开
<details></details> 本身不支持 height 过渡,强行加 transition: height .3s 没用。真实可行的方案只有两个:
- 用
max-height+overflow: hidden模拟:设一个足够大的值,比如max-height: 600px,再加transition: max-height .3s ease-in-out - 用 JS 动态读取高度:
element.scrollHeight,然后设为max-height再过渡;但要注意图片未加载完时scrollHeight可能偏小,得等load事件或用ResizeObserver
真正容易被忽略的是:如果内容含异步插入的文本或图片,scrollHeight 取值时机不对,动画就会中途截断或跳变。这时候宁可保守设个固定 max-height,也别赌 JS 读取的“实时高度”。











