当列表中的内容项被添加、移除或重新排列时,过渡效果可以帮助用户保持上下文。视图过渡提供了一种在元素的两种状态之间进行过渡的方法,方法是为元素指定唯一的 view-transition-name。当页面上的多个元素具有相同的过渡行为时,view-transition-class 允许您在 CSS 中定义一次该逻辑,而无需为每个唯一的 view-transition-name 重复该逻辑。这样可以使样式表易于维护,同时确保一组元素具有一致的动画。
实现步骤
分配唯一名称和共享类
在过渡期间需要单独跟踪的每个元素都必须具有唯一的
view-transition-name。<!-- Mandatory: Each element must have a unique view-transition-name --> <li style="view-transition-name: item-1" class="item">Item 1</li> <li style="view-transition-name: item-2" class="item">Item 2</li>如需应用共享样式,还需分配
view-transition-class。.item { view-transition-class: list-item; }定义共享过渡逻辑
将
::view-transition-group()伪元素与类选择器结合使用,可将样式应用于该组的所有成员。/* Targets any view transition group that has the 'list-item' class */ ::view-transition-group(.list-item) { animation-duration: 0.5s; animation-timing-function: ease-in-out; } /* Handle accessibility by respecting motion preferences */ @media (prefers-reduced-motion: reduce) { /* Disable all group transitions, including the default `root` group. */ ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; } }可选:定义进入动画和退出动画
使用
:only-child选择器为添加或移除的元素添加特定过渡效果。::view-transition-new()和::view-transition-old()伪元素是::view-transition-image-pair()伪元素的子元素,因此如果它是唯一的子元素,我们可以确定它是添加或移除的元素。/* A `::view-transition-new()` element is the only child if it wasn't present before the view transition, so it is an added element. */ ::view-transition-new(.list-item):only-child { animation-name: slide-in; /* Specify an animation duration if you want something different than the UA default of 0.5s */ animation-duration: 1s; } /* A `::view-transition-old()` element is the only child if it isn't present after the view transition, so it is a removed element. */ ::view-transition-old(.list-item):only-child { animation-name: slide-out; /* Specify an animation duration if you want something different than the UA default of 0.5s */ animation-duration: 1s; } @keyframes slide-in { from { translate: -100vw 0; } } @keyframes slide-out { to { translate: -100vw 0; } }触发过渡
将 DOM 更新封装在
document.startViewTransition()中。浏览器会捕获旧状态,执行更新,然后以动画形式过渡到新状态。function updateList(newData) { document.startViewTransition(() => { // All DOM changes inside this callback will be transitioned render(newData); }); }保持非过渡元素的互动性
视图过渡的工作原理是叠加 DOM 元素的快照,然后对快照进行过渡。这意味着在过渡期间,元素无法互动。如果存在未过渡的互动元素,您可以通过在视图过渡中停用触摸事件来使其可互动。
::view-transition {
/* Non-transitioned elements below the view transitions remain interactive */
pointer-events: none;
}
此外,默认情况下,:root 元素具有名为 root 的视图过渡,可实现默认的全页过渡。如果根元素没有变化,则会是两个相同快照之间的过渡,这些快照不具有互动性。由于我们只对特定元素(而非整个屏幕)进行转场,因此可以停用 root 转场。
:root {
/* Disable the root transition because we are only transitioning specific elements. */
view-transition-name: none;
}
后备策略
视图过渡是一种渐进增强。如果浏览器不支持 document.startViewTransition,DOM 更新仍应立即进行,从而提供功能正常但没有动画效果的体验。
if (document.startViewTransition) {
document.startViewTransition(() => updateDOM());
} else {
// Fallback: Perform the update without animation
updateDOM();
}
对于 CSS,无法识别 view-transition-class 或 ::view-transition-group() 类选择器的浏览器会直接忽略这些规则,并且不会应用任何动画。