height: auto 无法参与 transition 动画,因浏览器无法对非数值的 auto 进行插值计算;max-height 模拟是兼容性最佳方案,需配合 overflow: hidden 和显式 transition 声明。

直接写 transition: height 0.3s 并设置 height: 0 → height: auto 永远不会产生动画——这不是你代码写错了,是浏览器根本没法算中间帧。
为什么 height: auto 无法参与 transition
CSS 动画引擎只对可量化、可插值的数值做线性计算。height: auto 是布局阶段动态推导的结果,没有固定像素值,浏览器看到的是“0 → ?”,不是“0 → 248px”。DevTools 里能清楚看到高度在两值间硬切,毫无过渡痕迹。
常见错误现象包括:
- 点击展开按钮,内容瞬间弹出,收起却有动画(起点是 0,终点是 auto,单向失效)
- 加了
!important、反复读offsetHeight或强制重排也没用 -
transition: all看似覆盖所有属性,但对 auto 高度照样静默跳过
max-height 模拟是最轻量且兼容性最好的方案
把 height: auto 替换成一个“够大但不过大”的 max-height 值,配合 overflow: hidden,就能让过渡生效。它不依赖 JS,支持 IE10+,是多数生产环境首选。
立即学习“前端免费学习笔记(深入)”;
- 收起态:
max-height: 0; overflow: hidden; - 展开态:
max-height: 300px;(不能用none或fit-content,它们不可插值) - 必须显式声明:
transition: max-height 0.3s ease-in-out;(all不可靠) -
300px要略大于内容最大可能高度:粗略估算 =line-height × 最大行数 + padding × 2 + border × 2;设太小会截断,太大则动画前段“空跑”明显
grid-template-rows + fr 单位适合现代项目
如果你的容器可以改用 display: grid,用 grid-template-rows: auto 0fr → auto 1fr 是真正基于比例的平滑过渡,视觉节奏更自然。
- 必须加
overflow: hidden在父容器上,否则内容可能溢出 -
0fr不是0px,它表示该行不占空间但子元素仍参与布局,不会被截断 - 兼容性限于 Chrome 89+、Firefox 75+、Safari 14.1+;IE 和旧 Edge 完全不支持
- 不能用于
display: inline-grid或内联元素,动画会失效
Chrome 129+ 可直接用 calc-size(auto) 和 interpolate-size
截至 2026 年 9 月,Chrome 129 已正式支持 calc-size(auto),且可通过 interpolate-size: allow-keywords 全局启用 auto 插值——这是唯一能让 height: 0 → height: auto 原生过渡生效的方式。
- 写法一(局部):
height: calc-size(auto);,需保留 fallback:height: auto; - 写法二(全局):
:root { interpolate-size: allow-keywords; },之后所有height: auto都可参与过渡 - 注意:
interpolate-size目前仅 Chrome 支持,Firefox/Safari 尚未跟进;生产环境若需兼容,仍得降级到max-height或 JS 方案
真正容易被忽略的点是:无论用哪种方案,overflow: hidden 几乎总是必需的——漏掉它,内容就会在动画过程中意外撑开容器或溢出边界,导致视觉错乱。这个细节在调试时常常被当成“动画没生效”,其实只是内容没藏住。


















