grid-template-columns/rows 的 transition 大概率失效,因浏览器不支持对函数式语法(如 minmax、auto-fit)或轨道数量变化做插值;可靠方案是改用 0fr↔1fr、max-height+js 或 animate-css-grid。

直接改 grid-template-columns 或 grid-template-rows 加 transition,99% 的情况不会动——这不是你写错了,是浏览器根本不支持对这类结构化值做插值。
为什么 grid-template-columns 的 transition 大概率失效
浏览器只能对「可线性插值的纯数值型变化」做过渡,比如 200px → 300px 或 1fr → 2fr(注意:仅当整行/列都用 fr 且数量一致时才可能生效)。但以下写法一律跳过动画:
-
repeat(auto-fit, minmax(200px, 1fr))——auto-fit和minmax()是函数式语法,无法插值 -
1fr 1fr → 1fr 1fr 1fr—— 轨道数量变化,结构不匹配,浏览器不计算中间态 - 媒体查询中切换列数 —— 即使写了
transition,也是硬切,无过渡
真正能动的三种可靠路径
别在轨道定义上死磕,把动画目标转移到可插值的属性上:
-
用
grid-template-rows切换0fr ↔ 1fr:适合单行内容展开/收起。前提是父容器有确定高度上下文(如设了height、max-height,或被 flex 布局约束),且子元素设overflow: hidden -
用
max-height+scrollHeightJS 控制:最稳定,尤其适合多行文本、含图片或字体未加载完的场景。关键三步:先设max-height为scrollHeight,读offsetHeight触发重排,再设为0(收起)或反之(展开) -
用
animate-css-grid库:唯一能真正驱动网格项「从第2列滑到第3列」这种位移动画的方案。它监听 DOM 变化,用transform实现平滑位移,不依赖轨道定义是否可插值
gap 和列数必须同步更新,否则布局会崩
列数变多时如果 gap 还是 24px,间隙会被撑爆;列数变少时 gap 还没缩,内容就挤出容器。这不是样式冲突,是布局逻辑断裂:
- 每个断点里,
grid-template-columns和gap必须成对出现在同一规则块中,不能一个写在@media里,另一个写在根选择器里 - 避免用
rem或em写gap—— 字体缩放会意外放大间隙,优先用px或clamp(8px, 2vw, 16px) - 小屏调试时,临时删掉
gap看内容是否贴边,这是判断是否漏设的最快方式
复杂点往往藏在「前提条件」里
比如 0fr → 1fr 动画,缺一不可的三个条件:父容器显式声明 display: grid 和 grid-template-rows;内容区必须 overflow: hidden;子元素不能设 height 或 min-height。漏掉任意一个,动画就静音——不是报错,而是静默失效,很难排查。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











