不能用 height,必须换到 grid-template-rows + fr 单位,否则动画根本不会动;因为 height: 0 → auto 无法插值,而 0fr → 1fr 可被浏览器计算中间帧实现平滑过渡。

直接说结论:不能用 height,必须换到 grid-template-rows + fr 单位,否则动画根本不会动。
为什么 height: 0 → height: auto 过渡无效
CSS 的 transition 只能插值数值型属性,auto 不是数值,浏览器无法计算中间帧。写成 transition: height 0.3s 后 hover 切换,实际是“啪”一下跳出来,没有过渡过程。
常见错误现象:
- 样式写了
height: 0和height: auto,但动画不触发 - 用 JS 动态设
style.height = 'auto',依然没动画 - 误以为加了
overflow: hidden就能救,其实只是掩盖了跳变
怎么用 grid-template-rows: 0fr → 1fr 实现真正平滑过渡
核心是把“高度控制权”从 height 移交给 Grid 的行轨道,靠 fr 单位的可插值性驱动动画。
必须满足三个前提(缺一不可):
- 容器设
display: grid,且grid-template-rows显式声明为单行,如grid-template-rows: 0fr - 容器有确定的高度上下文:要么自身设
max-height/height,要么被父级 flex/grid 约束出可用空间 - 内容区加
overflow: hidden,否则0fr时内容可能溢出、遮挡其他元素
示例代码:
.accordion {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.3s ease;
overflow: hidden;
}
.accordion.open {
grid-template-rows: 1fr;
}
注意:1fr 不是固定像素,它会动态填满当前可用空间;0fr 表示“不参与分配”,视觉上就是收起状态。
容易踩的坑和兼容性细节
这些点不处理,动画大概率失效或错位:
- Safari 16.4 之前版本不支持
0fr→1fr过渡,需降级用max-height方案 - 内部有
position: absolute元素时,它们脱离文档流,1fr计算可能不含其高度,导致内容被裁剪 - 别混用
minmax()或fit-content()做动画,例如grid-template-rows: 0fr→minmax(0, max-content)在部分浏览器里不保证可插值 -
transition时间别设太短(如0.1s),Safari 下易跳帧;推荐0.25s–0.35s - JS 直接改
element.style.gridTemplateRows = '1fr'会丢失动画上下文——必须靠 class 切换触发 CSS 规则
什么情况下还是得退回 max-height 方案
不是所有场景都适合改 display: grid:
- 已有复杂布局,无法轻易改动父容器的
display类型 - 需要支持 IE(完全不支持
grid-template-rows动画) - 内容高度波动极大(比如含未加载图片),而你又没法等
img.onload再加.open类
此时用 max-height 是务实选择,但记得设一个略大于预期最大高度的值(如 max-height: 800px),并确保 transition 仅作用于该属性。
真正难的不是写对那几行 CSS,而是判断当前 DOM 结构、浏览器分布、内容动态性是否允许你安全启用 0fr → 1fr —— 它看起来简洁,背后全是约束条件。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











