height: 0 → auto 无动画因auto非数值,浏览器无法插值;max-height过渡最稳妥但需预设足够大固定值;JS测scrollHeight可精准适配任意高度;transform: scaleY()可绕过height冲突并GPU加速。

不能直接用 height 或 grid-template-rows 做过渡动画,必须绕过浏览器对 auto 和 fr 单位的插值限制。
为什么 height: 0 → height: auto 没动画
浏览器无法对 auto 插值——它不是数值,没有像素基准,transition 直接跳变。哪怕你写 height: 0 → 100%,在非 flex/grid 容器里百分比也无参考高度,照样失效。
- 常见错误现象:
.panel { height: 0; transition: height 0.3s; }+.panel.open { height: auto; }→ 内容瞬间弹出,无过渡 - 即使加了
overflow: hidden,只要目标值是auto,CSS 引擎就放弃生成中间帧 -
display: none/block切换也完全不可过渡,纯属强制重绘
用 max-height 是最稳妥的纯 CSS 方案
它能过渡,且兼容性好(IE10+),但必须用固定数值,不能写 none 或 auto。
- 设一个“足够大但不过量”的值:比如
max-height: 500px、max-height: 30em或max-height: 100vh - 值太小会截断内容;太大则收起末尾留白明显(动画结束但高度仍远高于内容实际高度)
- 必须配
overflow: hidden,否则内容会溢出可见区域 - 只过渡
max-height,别写transition: all,避免触发不必要的重绘
想真正适配任意高度?得靠 JS 测量 scrollHeight
纯 CSS 的 max-height 是估算,JS 才能拿到真实像素值。这是唯一能避免截断或留白的方法。
立即学习“前端免费学习笔记(深入)”;
- 展开前先获取内容元素的
element.scrollHeight,再设为内联style.maxHeight - 收起时设回
0,动画结束后清空内联样式(或设回max-height: 0) - 注意:不能直接对
height动画,仍要走max-height路线,只是值从 JS 注入 - 如果内容含图片或异步加载文本,需等
load或resize后重新测量
用 transform: scaleY() 替代高度动画(适合 Bootstrap 等框架)
当框架强制操作 height 内联样式(如 Bootstrap 的 .collapsing 类),用 scaleY 可绕过冲突,还能 GPU 加速。
- 给折叠容器加
transform-origin: top,确保从顶部缩放 -
.collapse:not(.show) { transform: scaleY(0); }+.collapse.show { transform: scaleY(1); } - 必须加
overflow: hidden防止缩放时内容溢出 - 父容器可能塌陷,需设
min-height或占位元素维持布局
真正麻烦的从来不是怎么写动画,而是怎么让动画结束时 DOM 高度归零、内容不错位、父容器不跳动——这些细节往往在 JS 事件(如 shown.bs.collapse)和 CSS 时序没对齐时暴露出来。


















