grid中用grid-template-rows实现展开动画需设0fr→fit-content(300px)并整体重设属性,因auto不可过渡、fr可插值,且必须配合transition和overflow: hidden,旧浏览器需降级为flex+max-height方案。

Grid 里用 grid-template-rows 控制展开高度
直接靠 height: 0 + overflow: hidden 做展开收起,在 Grid 容器里往往失效——因为 Grid 会按轨道(track)分配空间,height 不影响行高计算。真正可控的是 grid-template-rows:把详情行设为 0fr(折叠)或 auto(展开),Grid 会重新布局。
常见错误是写成 grid-template-rows: 1fr 0fr 然后试图只改第二项——不行,必须整个属性重设,否则浏览器不触发重排。
- 折叠状态用
grid-template-rows: auto 0fr,确保第二行不占空间 - 展开状态用
grid-template-rows: auto auto或auto fit-content(200px)(限制最大高度) - 配合
transition: grid-template-rows 0.25s ease实现平滑过渡(注意:仅支持长度值和fr单位,auto不能直接过渡,需用fit-content()或固定像素兜底)
用 fit-content() 替代 auto 让过渡生效
auto 本身无法参与 CSS 过渡,这是最常被忽略的坑。想让展开有动画,得把目标值换成可计算的尺寸。推荐用 fit-content(300px):它既允许内容撑开(不超过 300px),又能让浏览器算出具体像素值用于过渡。
示例:
/* 折叠 */
.container { grid-template-rows: auto 0fr; }
/* 展开 */
.container.is-expanded { grid-template-rows: auto fit-content(300px); }
- 避免写死
200px,内容超长会被截断;fit-content()更安全 - 如果内容高度差异大,可配合
max-height+overflow: hidden双保险 - Firefox 对
fit-content()支持良好,Chrome 94+ 也没问题,IE 不支持——需 fallback
JavaScript 切换 class 时注意重排时机
直接 element.classList.toggle('is-expanded') 后立刻读取 offsetHeight 或触发动画,可能拿不到新布局——因为 class 切换和样式计算不是同步的。必须等浏览器完成样式计算再执行后续逻辑。
- 用
getComputedStyle(element).gridTemplateRows验证是否已应用新值 - 需要测量展开后高度?加
requestAnimationFrame延迟一帧:element.classList.add('is-expanded'); requestAnimationFrame(() => { console.log(element.scrollHeight); }); - 如果用 React/Vue,确保 class 更新后 DOM 已 commit(比如 useEffect 的 flush 阶段或 nextTick)
兼容性兜底:IE 或旧 Safari 下降级为 Flex
Grid 的 grid-template-rows 过渡在 Safari 14.1 之前不支持,IE 完全不支持。真要兼容,得准备降级方案,而不是只加前缀。
- 检测支持:
CSS.supports('display', 'grid') && CSS.supports('transition', 'grid-template-rows') - 不支持时,切换到 Flex 布局:
flex-direction: column+max-height+overflow: hidden - 别试图用
@supports在 CSS 里覆盖 Grid 行高——JS 控制更可靠
细节在于:Grid 方案干净但要求现代环境;Flex 降级要处理好 padding/margin 溢出和动画卡顿,尤其是内容动态加载时。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











