View Transitions API 删除动画需用 document.startViewTransition() 包裹 DOM 更新,依赖唯一 data-view-transition-name、避免 flex/grid 布局干扰,并配合 ::view-transition-old/new 伪元素 CSS 实现;Chrome/Edge/Opera 支持,Firefox/Safari 需降级为 max-height+opacity 动画。

View Transitions API 能让列表项删除时自动产生平滑位移动画,但目前仅 Chromium 111+(含 Edge、Chrome、Opera)原生支持,Firefox 和 Safari 尚未实现——别在生产环境默认启用,必须降级兜底。
View Transitions API 删除动画怎么写
核心是用 document.startViewTransition() 包裹 DOM 更新操作,浏览器会自动捕获前/后状态并生成元素位移补间。不是 CSS 动画,不依赖 transition 或 @keyframes:
- 必须在用户交互(如 click)或异步微任务中调用,不能在
DOMContentLoaded等纯初始化时机触发 - 只能包裹一次 DOM 修改:比如
listEl.removeChild(itemEl)或listEl.innerHTML = newHtml,不能在里面再嵌套 View Transition - 删除前需确保目标元素有稳定
key(如data-view-transition-name="item-123"),否则浏览器无法匹配新旧节点
示例:
function deleteItem(itemEl) {
const id = itemEl.dataset.id;
document.startViewTransition(() => {
itemEl.remove(); // 或 listEl.replaceChildren(...filteredItems)
});
}
为什么加了 View Transition 还没动画
常见失效原因不是代码写错,而是底层约束没满足:
立即学习“前端免费学习笔记(深入)”;
-
data-view-transition-name缺失或重复:每个参与过渡的元素必须有唯一、稳定的 name,且删除前后该 name 要能对应上(比如删的是data-view-transition-name="item-42",新 DOM 里就不能再出现同名元素) - 父容器用了
display: flex或grid:View Transition 在弹性布局下对位置计算不准确,容易导致位移错乱;临时方案是外层加 wrapper 并设display: block - CSS 强制重排:在 transition 过程中读取
offsetTop、getBoundingClientRect()等会中断动画帧;改用requestAnimationFrame延迟到下一帧 - 元素被
transform或position: absolute干扰:View Transition 依赖文档流自然位置,绝对定位元素可能直接“瞬移”
View Transition 必须搭配的 CSS 规则
API 自动补间,但视觉细节要靠 CSS 控制:
- 给参与过渡的元素加
view-transition-name: item-123(注意不是 data 属性,是 CSS 属性),且必须带前缀view-transition-name,不能简写 - 在
@property或:root中定义--view-transition-new-item和--view-transition-old-item可选变量,用于自定义入场/离场样式 - 关键降级样式:
::view-transition-old(item-123)和::view-transition-new(item-123)伪元素必须显式设z-index,否则会被其他内容遮盖 - 不要在伪元素里用
display: none或visibility: hidden:这会让浏览器跳过该节点的过渡计算
最小可用 CSS:
::view-transition-old(item-*) {
z-index: 1;
animation: fade-out 0.25s ease-out;
}
::view-transition-new(item-*) {
z-index: 2;
animation: fade-in 0.25s ease-in;
}
@keyframes fade-out { to { opacity: 0; } }
@keyframes fade-in { from { opacity: 0; } }
兼容性兜底必须手动实现
Firefox/Safari 用户看到的是无动画直删,体验断层明显。不能只靠 if ('startViewTransition' in document) 判断就放弃处理:
- 检测失败时,立即 fallback 到
max-height + opacity方案,并确保 JS 删除逻辑走同一套transitionend监听路径 - 避免同时开启两种动画:View Transition 活跃时,禁用所有手动
max-height类切换,否则 DOM 状态冲突 - 滚动容器内列表项删除时,View Transition 可能因滚动锚点偏移导致位移抖动;此时应优先用
scroll-behavior: smooth+ 手动scrollIntoView({ block: 'nearest' })补偿
真正麻烦的不是写动画,而是让 View Transition 的“自动识别”和你手写的 DOM 结构、CSS 布局、滚动行为全部对齐——它不报错,只静默失效。


















