定向导航过渡

单页应用 (SPA) 通过替换网页内容(而不是导航到新网页)来提供导航外观。默认情况下,内容只是被替换,没有任何过渡效果。方向性过渡可以直观地强化视图之间的空间关系。

通过从用户移动的方向滑入新内容,您可以创建应用结构的心智模型。例如,产品网站可能会在用户点击“前进”时显示向右过渡效果,在用户点击“后退”时显示向左过渡效果;或者,幻灯片可能会向上和向下过渡,以显示下一张和上一张幻灯片。

实施步骤

  1. 检测导航方向:确定用户在应用流程中是“向前”还是“向后”移动。如何检测方向取决于您的应用场景。
  2. 使用类型触发过渡:将 types 数组中的方向传递给 document.startViewTransition(),以对过渡进行分类。
  3. 使用 CSS 定义方向性动画:使用 :active-view-transition-type() 伪类根据导航类型应用特定动画。

定义关键帧

定义每个方向的滑动动画。为了获得最佳性能,请使用 transform 属性或各个转换属性(scale、rotate 和 translate)为位置变化添加动画效果。opacity 通常也具有良好的性能,但请避免在未事先验证其他 CSS 属性不会触发布局或绘制的情况下为其添加动画效果。

/* Slide an element out to the left */
@keyframes slide-to-left {
  /* Mandatory: animate `transform` instead of inset properties for better performance. */
  to { transform: translateX(-100%); }
}

/* Slide an element in from the right */
@keyframes slide-from-right {
  from { transform: translateX(100%); }
}

/* Slide an element out to the right */
@keyframes slide-to-right {
  to { transform: translateX(100%); }
}

/* Slide an element in from the left */
@keyframes slide-from-left {
  from { transform: translateX(-100%); }
}

设置共享动画设置

使用 ::view-transition-group(root) 选择器应用在所有过渡之间共享的动画设置。

::view-transition-group(root){
  animation: 0.4s ease-in-out both;
}

应用方向动画

使用 active-view-transition-type 伪类,在“向前”或“向后”类型处于活动状态时专门定位到过渡视图。

/* MANDATORY: Apply forward animations when the 'forward' type is active */
html:active-view-transition-type(forward)::view-transition-old(root) {
  animation-name: slide-to-left;
}
html:active-view-transition-type(forward)::view-transition-new(root) {
  animation-name: slide-from-right;
}

/* MANDATORY: Apply backward animations when the 'backward' type is active */
html:active-view-transition-type(backward)::view-transition-old(root) {
  animation-name: slide-to-right;
}
html:active-view-transition-type(backward)::view-transition-new(root) {
  animation-name: slide-from-left;
}

触发转换

导航时,将适当的类型传递给 startViewTransition 方法。

const transitionType = yourTransitionTypeLogic();
const updateDOM = yourUpdateDOMLogic();

document.startViewTransition({
  update: updateDOM,
  types: [transitionType] // Matches the CSS :active-view-transition-type() selectors
});

无障碍

始终尊重用户对减少动画效果的偏好设置,停用或简化动画。

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(root) {
    animation: none !important;
  }
}

后备策略

View Transitions API 是一种渐进增强功能。在不受支持的浏览器中,document.startViewTransition 将为 undefined。您必须将导航逻辑封装在特征检测检查中,以确保 DOM 更新仍会立即发生,而不会产生动画,如以下辅助函数所示。

/**
 * Navigates to a new view with a directional transition.
 * @param {Function} updateDOM - Callback to update the DOM state.
 * @param {string} direction - Either 'forward' or 'backward'.
 */
function navigate(updateDOM, direction) {
  // Feature detect for browsers that do not support View Transitions
  if (!document.startViewTransition) {
    updateDOM();
    return;
  }

  // Start transition with the specific navigation type
  document.startViewTransition({
    update: updateDOM,
    types: [direction] // Matches the CSS :active-view-transition-type() selectors
  });
}