grid-template-rows 不可动画,因其为非可插值属性;应改用 max-height 或 transform 实现平滑过渡。
grid-template-rows 里用 0fr → 1fr 做过渡,根本不是“不自然”,而是根本不动画——浏览器直接跳变,没中间帧。
grid-template-rows 本身不可动画W3C 明确标注 grid-template-rows 和 grid-template-columns 是 not animatable 属性。
哪怕你写了 transition: grid-template-rows 0.3s,浏览器也只会忽略过渡,执行完立刻重排布局。
常见错误现象:
element.style.gridTemplateRows 没缓动overflow: hidden + 内容高度小造成的视觉欺骗为什么 fr 单位无法插值:
fr 不是像素,是“剩余空间的弹性份额”max-height 过渡比 fr 更可靠真正能平滑过渡的是数值型、可插值的属性,比如 max-height、transform、opacity。
立即学习“前端免费学习笔记(深入)”;
使用 max-height 的关键约束:
max-height: 0),不能用 none 或 fit-content
max-height: 400px)overflow: hidden,否则溢出会破坏动画效果getBoundingClientRect().height 再写入,但会失去纯 CSS 简洁性示例结构:
.accordion-panel {max-height: 0;overflow: hidden;transition: max-height 0.25s ease, opacity 0.25s ease;}.accordion-panel.is-open {max-height: 400px;opacity: 1;}
transform: scaleY() 是更稳的替代方案对单个网格项做缩放,比动整个轨道更轻量、更可控,且所有现代浏览器都支持 transition: transform。
实操要点:
height 或 min-height,再用 transform: scaleY() 控制显隐transform: scaleY(0) + transform-origin: top
transform: scaleY(1)
scaleY(0) 完全隐藏时触发文字重排,可加 opacity: 0 同步控制注意:它不改变文档流,热区和点击区域仍按原始尺寸响应,必要时需用 pointer-events: none 或伪元素补足。
fr 单位天生不适合动画,这不是 bug,是设计使然。想让 Grid 区域“动起来”,得把动画压力从轨道定义转移到子元素自身——要么靠 max-height 模拟高度变化,要么靠 transform 做视觉缩放。硬刚 grid-template-rows,只会反复踩进重排陷阱。