height: 0 → height: auto 无法平滑过渡,因auto无像素基准;可靠方案是用max-height+overflow:hidden模拟,或Chrome129+的interpolate-size,或grid-template-rows:0fr→minmax(0,max-content)。

不能直接用 height: 0 → height: auto 实现平滑过渡,浏览器不支持对 auto 插值,动画必然跳变。 唯一可靠方案是绕过 height 本身,用可插值的替代属性控制视觉高度变化。
为什么 height: 0 → height: auto 一定失败
浏览器动画引擎需要起始值和结束值都是确定的数值(如 0px、128px),才能计算中间帧。auto 是运行时计算值,没有像素基准,transition 直接被忽略。即使加了 overflow: hidden,只要目标是 auto,就无动画。
-
height: 0初始状态受padding、border影响,实际渲染可能不为 0 -
height: 100%在无明确父高上下文时等价于auto,同样不可插值 - 所有主流浏览器(包括 Chrome 129+)对
height: auto的过渡都视为非法,不触发任何帧
用 max-height 模拟是最稳 fallback 方案
设一个足够大的固定值(大于内容最大可能高度),让浏览器能在 0 和该值之间线性插值,配合 overflow: hidden 视觉上就是“展开/收起”。
- 取值建议:
max-height: 500px或max-height: 100vh;太小会截断内容,太大则收起时有明显延迟感 - 必须同时写
overflow: hidden,否则溢出内容会显示出来 - 不要用
display: none切换状态——它会中断过渡,用 class 控制max-height变化即可 - 示例:
.panel { max-height: 0; overflow: hidden; transition: max-height 0.3s ease-in-out; }<br>.panel.open { max-height: 500px; }
Chrome 129+ 可试 interpolate-size: allow-keywords,但别依赖
这是目前唯一能让 height: 0 → height: auto 真正生效的原生方案,但它只在 Chrome 129+ 生效,Safari 和 Firefox 截至 2026 年 9 月仍完全不支持。
立即学习“前端免费学习笔记(深入)”;
- 必须写在**父容器**上,不是目标元素本身:
.container { interpolate-size: allow-keywords; } - 目标元素仍需显式声明
height: 0和height: auto,且transition必须包含height - 中间若有
flex或grid容器,继承链可能断裂,建议就近设在直接父级 - 老浏览器会直接忽略该属性,所以
height: auto必须保留作为兜底,不能删
真正内容驱动的方案:用 grid-template-rows + fr
如果父容器有确定高度上下文(比如设了 height 或 min-height),可用 grid-template-rows: 0fr → minmax(0, max-content) 实现精准、无 magic number 的过渡。
- 前提:父容器必须显式声明
display: grid和grid-template-rows,且内容区加overflow: hidden -
0fr不等于height: 0,它是轨道尺寸为 0,需靠overflow: hidden隐藏内容 - 优势是无需预估高度,浏览器能根据
max-content自动算出目标尺寸并插值 - 注意:若父容器是
flex或未设高度,则fr单位无参考,动画失效
最易踩的坑是试图“修好 height: auto”,其实应该放弃它——浏览器设计上就没打算让它可动画。真正健壮的实现,永远要基于可插值单位(px、fr、vh)或浏览器新特性(interpolate-size)做兜底分层,而不是赌某个 CSS 属性“理论上应该可以”。


















