details标签无法直接用CSS transition实现展开动画,必须通过JavaScript监听toggle事件,动态设置内容区max-height并强制重排;箭头旋转需结合details[open]选择器和transform过渡;scrollHeight读取需注意图片加载时机和布局刷新。

details 标签本身不支持 transition 动画
直接给 <details> 或 <summary> 加 transition: max-height 0.3s 完全无效——因为浏览器原生的 open 属性切换不触发 height/max-height 变化,内部内容区也没有初始 max-height 值,CSS 无法插值。你看到的“瞬间展开”是原生行为,不是动画缺失,而是机制不同。
用 JavaScript 监听 toggle 事件 + max-height 模拟动画
必须手动接管展开/收起逻辑,核心是动态设置内容区(<details> 下第一个非 <summary> 子元素)的 max-height,并触发重排让过渡生效:
-
overflow: hidden必须加在内容区上,否则高度变化时内容会溢出或撑开容器 - 展开前先设
max-height: 0,再调用content.offsetHeight强制重排,再设为content.scrollHeight - 收起时反向操作:先设目标高度,再重排,再设回
0 - Safari 中
scrollHeight在内容含图片时可能读错,建议在offsetHeight === 0时额外调用getComputedStyle(content).height触发布局刷新
const details = document.querySelector('details');
const content = details.querySelector(':scope > *:not(summary)');
details.addEventListener('toggle', () => {
if (details.open) {
content.style.maxHeight = '0';
content.offsetHeight;
content.style.maxHeight = content.scrollHeight + 'px';
} else {
content.style.maxHeight = content.scrollHeight + 'px';
content.offsetHeight;
content.style.maxHeight = '0';
}
});
summary 箭头旋转动画要配合 open 状态写
<summary> 支持 :hover 和 transform,但箭头翻转不能只靠伪类,必须绑定 <details> 的 open 状态:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 用
details[open] summary { transform: rotate(90deg); }控制展开时的图标方向 - 必须显式加
transition: transform 0.2s ease,且确保<summary>是 inline 元素(默认就是) - 若想隐藏原生小三角,需同时设
list-style: none和summary::marker { display: none; },但注意::marker在 Safari 15.4 以下不支持
max-height 过渡的硬伤:高度估算不准
即使 JS 计算 scrollHeight,也常因字体加载、行高计算时机、内联样式未生效等原因导致值偏小或偏大,表现为动画中途卡住或收不严:
立即学习“前端免费学习笔记(深入)”;
- 避免用
max-height: 0 → auto,CSS 不支持auto插值 - 不要设固定上限如
max-height: 500px,内容超长时会截断 - 更稳妥的做法是:展开前先临时设
visibility: hidden; height: auto;,读完scrollHeight后立刻恢复visibility: visible并应用max-height - 如果内容含图片,务必等
img.onload或用requestAnimationFrame延迟读取,否则scrollHeight取的是占位高度


















