grid-row不可动画化,因规范禁止;需用CSS变量控制grid-template-rows(如--row-height:0fr→1fr),配合overflow:hidden和显式声明,或JS动态设值实现过渡。

为什么直接用 grid-row 做过渡会失败
因为 grid-row 是不可动画化属性,浏览器压根不支持对它做 transition。你写 transition: grid-row 0.3s,实际毫无反应——不是写错了,是规范禁止。常见表现是:类名一换,元素瞬间跳到新位置,毫无缓动。
grid-template-rows 配合 CSS 变量能动,但必须守死三件事
想靠变量驱动 grid-template-rows 实现“高度自动过渡”,核心是把内容行高度从 0fr → 1fr,再用变量控制这个切换过程。但以下三点漏掉任一,动画就断:
-
grid-template-rows必须显式声明为单行承载内容,例如grid-template-rows: 0fr;(不能是auto或minmax()) - CSS 变量必须用于定义行高比例,如
--row-height: 0fr;,然后在grid-template-rows: var(--row-height);中引用 - 必须配合
overflow: hidden,否则未展开时内容可能溢出、遮挡其他元素
示例:
.panel {
display: grid;
grid-template-rows: var(--row-height, 0fr);
overflow: hidden;
transition: grid-template-rows 0.25s ease-in-out;
}
.panel.is-open {
--row-height: 1fr;
}
用 JS 动态注入变量值比纯 CSS 更可控
纯 CSS 变量只能做离散切换(0fr ↔ 1fr),没法插值中间帧。如果需要更细腻的展开节奏(比如慢启快收),就得用 JS 控制变量数值:
- 监听展开动作后,用
element.style.setProperty('--row-height', '0.3fr')逐步更新 - 搭配
requestAnimationFrame实现每帧微调,避免卡顿 - 注意:不要在动画中同步改容器尺寸(如
height: auto或max-height),否则getBoundingClientRect()快照会错位,导致位移偏移
真正“自动”的边界在哪
所谓“自动”,只是指不硬编码像素值,不代表完全脱离约束。1fr 的行为依赖父容器剩余空间,如果父容器 height 被限制(如 max-height: 300px),1fr 就会压缩内容,甚至触发滚动条——这时候视觉上就不是“撑开”,而是“裁切”。所以,用变量 + Grid 做高度过渡,本质是让布局响应内容,而非让动画感知内容;真要动态测高+逐帧动画,还是得靠 JS 配合 offsetHeight。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











