grid-template-rows: 0fr → 1fr 能实现平滑过渡,因 fr 是可插值弹性单位,表示剩余空间分配比例而非固定长度;需满足三前提:容器有确定高度上下文、显式声明 grid-template-rows、内容区 overflow: hidden。

为什么 grid-template-rows: 0fr 无法触发过渡
直接写 transition: grid-template-rows 0.3s 并把 grid-template-rows 从 0fr 切到 1fr,几乎肯定没动画——浏览器不支持对 fr 单位做插值计算,0fr 和 1fr 都是符号化轨道定义,不是可度量长度,CSS 引擎没法生成中间帧。
真正能过渡的,是带明确尺寸的值(比如 0px → 200px),或 auto(但需配合高度测量)。
-
0fr不等于0px:它表示“分配零份额”,实际高度由内容撑开,不是固定尺寸 - 用
max-height模拟过渡更常见,但会受内容高度不可预知影响(过高则慢吞吞收起,过低则截断) - Grid 折叠想用原生布局能力,就得绕过
fr,改用minmax()+ 固定单位组合
用 minmax(0, max-content) + height 触发真实过渡
核心思路:让 grid track 的高度由子元素 height 决定,而 height 可以被过渡;minmax(0, max-content) 让 track 允许收缩到 0,同时不限制展开上限。
关键不在 grid-template-rows 自身过渡,而在控制其内部元素的高度变化,并让 grid 自动响应。
- 给折叠区域的直接子容器(如
.panel-content)设height: 0/height: auto,并加overflow: hidden - 对该子容器设置
transition: height 0.3s ease-in-out - grid 容器设
grid-template-rows: minmax(0, max-content),这样 track 会随子元素height动态缩放 - 切记:不能对
grid-template-rows加 transition,要对子元素的height加
.accordion {
display: grid;
grid-template-rows: minmax(0, max-content);
}
.accordion > .panel-content {
height: 0;
overflow: hidden;
transition: height 0.3s ease-in-out;
}
.accordion.active > .panel-content {
height: auto;
}
如何正确获取内容真实高度来避免 height: auto 失效
height: auto 本身不能过渡——浏览器不知道“auto”该变成多少像素。所以必须先测量内容高度,再显式设为具体像素值。
纯 CSS 做不到测量,必须用 JS 触发一次“展开→读高→再设高”流程,否则 height: auto 在过渡开始时就是 0 → auto(即 0 → 无定义),动画跳变。
- 点击展开时,先临时移除
overflow: hidden和height,强制渲染出自然高度 - 用
element.scrollHeight读取内容真实高度 - 再设回
height: ${scrollHeight}px,此时过渡才有效 - 收起时可直接设
height: 0,无需再测(因为已知目标是 0) - 过渡结束后,用
transitionend清理内联height,恢复height: auto以适应后续内容变动
兼容性与布局干扰要注意什么
Grid + minmax(0, max-content) 在 Safari 15.4+、Chrome 105+、Firefox 102+ 支持良好,但旧版 Safari 对 minmax(0, ...) 中的 0 解析异常,可能当 minmax(min-content, ...) 处理,导致无法收缩到底。
- 稳妥写法是
minmax(0px, max-content),用0px替代0,明确单位 - 如果面板里有
margin或padding,它们不会被height过渡包含,需确保内容区自身含内边距,或用box-sizing: border-box - Grid 容器若还设置了
align-items: start/center,可能干扰子项垂直定位,建议保持默认stretch或显式设align-items: flex-start - 不要在
.panel-content上设display: grid/flex并期望子项自动撑高——某些情况下会破坏scrollHeight测量精度
真正难的不是写几行 CSS,而是让 JS 测高逻辑和 CSS 过渡节奏严丝合缝;差一帧,就卡住或闪一下。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











