浏览器不支持 grid-column、grid-row 和 grid-template-rows/columns 的 transition,因其为离散值,无中间状态;仅 transform、opacity、filter、gap 等可动画,需用 transform 模拟位置迁移并避免 layout thrashing。

不能直接给 grid-column 或 grid-row 加 transition,浏览器不支持这些属性的插值计算,写了也白写。
为什么 grid-template-rows/columns 无法动画
这类布局定义属性是离散值,比如 grid-template-columns: 1fr 2fr → 2fr 1fr,中间没有可计算的“半状态”,transition 完全失效。你看到的跳变不是性能问题,而是根本没触发动画逻辑。
- 错误写法:
transition: grid-template-columns 0.3s—— 在所有主流浏览器中均无效果 - 真正能动的只有合成层友好属性:
transform、opacity、filter、z-index(仅在层叠上下文变化时) -
gap和grid-gap可以过渡,但仅限于数值变化(如gap: 8px → 24px),不影响位置重排动画
用 transform 模拟位置迁移(animate-css-grid 的核心思路)
子元素位置变化的本质,是它在网格轨道中的起始/结束线变了。但你不能动那几条线,只能让它“看起来”在动——靠 transform: translate() 把它从旧位置滑到新位置。
- 先用
getComputedStyle或ResizeObserver捕获增删前后的布局坐标(getBoundingClientRect()) - 对新增元素:初始设
opacity: 0; transform: scale(0.95),再加 class 触发opacity: 1; transform: scale(1) - 对被挤走的现有元素:用
requestAnimationFrame在 DOM 更新后立即读取新位置,然后transform: translate(x, y)补上偏移量 - 关键细节:必须加
will-change: transform, opacity,否则 Safari 和旧版 Chrome 会掉帧
动态增删时的 stagger 动画控制
单纯给所有子项统一加 transition-delay 不可靠,因为增删顺序、DOM 插入时机、CSSOM 更新节奏都不可控。真正在意 stagger 效果,得用 CSS 自定义属性 + JS 控制。
立即学习“前端免费学习笔记(深入)”;
- 给每个子元素设
style.setProperty('--stagger', `${index * 0.08}s`) - CSS 中写:
transition: transform 0.35s cubic-bezier(0.22, 0.61, 0.36, 1) var(--stagger), opacity 0.35s var(--stagger) - 删除时别用
display: none,改用opacity: 0; transform: translateY(-10px); pointer-events: none,再监听transitionend后移除 DOM - 注意:Firefox 对大量
transform元素同时 stagger 渲染较慢,加translateZ(0)强制 GPU 加速
最易被忽略的是 layout thrashing:在一次 JS 执行中反复读写 offsetTop/getBoundingClientRect/then style 修改,会强制同步重排。所有坐标读取必须聚合成一次 batch,所有样式写入放在最后——哪怕只差一个 offsetLeft 调用,都可能让动画卡顿一帧。


















