grid-template-columns/rows 等结构属性无法 transition,因浏览器无法插值不同轨道定义;可动画的仅有子项 transform 和 opacity,需 js 计算位移并配合 requestanimationframe 实现平滑迁移。

不能直接用 transition 动画 grid-template-columns 或 grid-template-rows —— 浏览器会静默忽略,你写的过渡毫无效果。
为什么 grid-template-* 无法 transition
这些属性描述的是网格轨道的结构(比如 "1fr minmax(100px, 1fr) 200px"),不是单一数值,浏览器无法在两组不同单位、不同函数、不同数量的轨道定义之间插值。你加了 transition: grid-template-columns 0.3s,控制台不报错,但动画就是不发生——这不是 bug,是规范限制。
同理,grid-area、grid-template-areas、grid-auto-flow 全部不可动画。别试 transform: scale() 去“模拟”列宽变化,它只会拉伸内容,破坏对齐和间隙逻辑。
真正能动的只有子元素的 transform 和 opacity
Grid 容器布局不变,靠移动、缩放、淡入淡出子项来制造“重新布局”的视觉效果:
- 给每个网格项加
transition: transform 0.3s ease, opacity 0.2s; - 用 JS 计算目标位置(比如某项从第 1 行第 2 列 → 第 2 行第 1 列),再设
transform: translateX(...px) translateY(...px) - 如果要隐藏/显示项,用
opacity: 0; visibility: hidden;替代display: none,否则动画跳过 - 避免在动画中同步改容器尺寸(如
height: auto),否则getBoundingClientRect()快照会错位
想省事就用 animate-css-grid
它封装了上述所有细节,只做两件事:监听 DOM 变化 + 用 transform 模拟迁移。安装后:
import { wrapGrid } from 'animate-css-grid';
wrapGrid(document.querySelector('.grid'));
它自动响应以下变更并生成协调动画:
-
grid-column/grid-row改变 → 元素滑动到新格线 -
grid-template-columns变更 → 所有子项按新列宽重新分布,带位移缓动 -
gap动态调整 → 间距渐变,不突兀
注意:它依赖快照对比,所以不要在动画帧内同步修改容器 width、height 或 padding,否则位移计算失准。
手动实现时最容易漏掉的三件事
哪怕你写 JS + CSS 自己搞,以下三点任缺其一,动画就会卡顿、错位或完全不触发:
- 没在重排 DOM 后强制重绘(例如读取
offsetHeight),导致浏览器把旧位置当起点 - 没用
requestAnimationFrame批量设置目标transform,而是同步赋值,动画被合并成一帧 - 子项没设
position: relative(或absolute),导致transform相对于非预期祖先定位
复杂点在于:Grid 的隐式轨道、minmax()、fit-content() 都会让坐标计算变脆弱,纯 CSS 搞不定,必须 JS 参与。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











