Transiciones entre documentos

Las transiciones de vistas entre documentos te permiten crear transiciones fluidas, similares a las de una app, entre diferentes páginas de una aplicación de varias páginas (MPA). De forma predeterminada, el navegador realiza un fundido cruzado, pero puedes personalizarlo para que coincida con la estética de tu sitio.

Pasos de implementación

1. Habilita las transiciones de vistas entre documentos

Tanto la página de origen como la de destino deben habilitar las transiciones de vistas para que el navegador las active durante la navegación.

/* Respect user's preference for reduced motion */
@media (prefers-reduced-motion: no-preference) {
  /* Add to a global stylesheet shared by both pages */
  @view-transition {
    /* Enables transitions for same-origin navigations */
    navigation: auto;
  }
}

2. Personaliza las animaciones de transición (opcional)

Puedes segmentar los estados antiguos y nuevos de la transición con seudoelementos para crear efectos como diapositivas o revelaciones.

/* Customizing the outgoing page animation */
::view-transition-old(root) {
  /* Move the old page out to the left */
  animation: 0.4s ease-in both slide-out;
}

/* Customizing the incoming page animation */
::view-transition-new(root) {
  /* Move the new page in from the right */
  animation: 0.4s ease-out both slide-in;
}

@keyframes slide-out {
  to { transform: translateX(-20%); opacity: 0; }
}

@keyframes slide-in {
  from { transform: translateX(100%); }
}

3. Crea transiciones direccionales (opcional)

Es posible que quieras usar diferentes efectos de transición según las páginas entre las que navegues. Por ejemplo, cuando navegas de una página principal a una de contacto, es posible que quieras que el contenido nuevo aparezca desde la derecha. Cuando se navega de regreso a la página principal, no tendría sentido tener el mismo efecto.

Si la página a la que navegas siempre tendrá el mismo tipo de transición, independientemente de cómo llegues a ella, puedes especificarlo con types en la regla @view-transition.

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
    /* Specify the types of view transitions that will always be used on this page. */
    types: previous;
  }
}

También puedes especificar de forma condicional los tipos de transición dentro de un objeto de escucha de eventos para pagereveal.

window.addEventListener("pagereveal", async (e) => {
  if (e.viewTransition && window.navigation?.activation) {
    // Use application-specific logic to compute a transition type
     const transitionType = yourTransitionTypeLogic(navigation.activation.from, navigation.activation.entry);
    e.viewTransition.types.add(transitionType);
  }
});

Luego, usa el pseudoselector :active-view-transition-type() para aplicar las diferentes animaciones para cada tipo.

:active-view-transition-type(next) {
  &::view-transition-old(root) {
    animation-name: slide-out-next;
  }

  &::view-transition-new(root) {
    animation-name: slide-in-next;
  }
}
:active-view-transition-type(previous) {
  &::view-transition-old(root) {
    animation-name: slide-out-previous;
  }

  &::view-transition-new(root) {
    animation-name: slide-in-previous;
  }
}

Estrategias de resguardo

Si un navegador no admite las transiciones de vistas o las transiciones de vistas entre documentos, realizará una navegación de página instantánea estándar. Las transiciones de vistas entre documentos son una mejora progresiva; la funcionalidad principal del sitio no se ve afectada.

Para verificar la compatibilidad en JavaScript, haz lo siguiente:

if ('onpagereveal' in window) {
  // Browser supports cross-document view transitions
}

Si un navegador no admite la API de Navigation, no podrás usarla para determinar un tipo de transición. Usa un método alternativo para determinar el tipo de transición o proporciona un tipo de transición de resguardo. De lo contrario, el navegador realizará una navegación de páginas instantánea estándar.

Para verificar la compatibilidad en JavaScript, haz lo siguiente:

if (window.navigation?.activation) {
  // Browser supports the Navigation API
}