Un patrón común para las páginas web es usar JavaScript para reemplazar de forma dinámica el contenido de una página sin cargar un documento HTML nuevo y completo. Esto se denomina aplicación de página única o SPA. Las transiciones de vista te permiten mostrar continuidad o contexto entre las páginas de tu SPA.
Transiciones de página completa
Cuando el usuario navega a una vista nueva en tu SPA, el framework reemplaza el DOM con contenido nuevo. Esto hace que el contenido simplemente aparezca, pero ¿qué sucede si quieres proporcionar una transición entre el contenido actual y el nuevo?
Las transiciones suelen mostrar las vistas antiguas y nuevas de forma simultánea, por ejemplo, atenuando la vista antigua mientras se muestra la nueva. Dado que se reemplaza el contenido existente, esto era un desafío antes de las transiciones de vista.
Para usar las transiciones de vista, deberás incluir la lógica para cambiar el DOM en una devolución de llamada. Para estos ejemplos, tenemos una implementación básica del router proporcionada por un componente web llamado MyRouter
. La forma en que habilites las transiciones de vistas dependerá del enrutador y del framework que uses.
document.startViewTransition(() => updateTheDOMSomehow());
Esto habilita la transición predeterminada, que atenúa la vista anterior mientras se muestra la nueva.
¿Qué sucede aquí? Cuando llamas a document.startViewTransition()
, el navegador toma una instantánea de la vista anterior. Luego, llama a la función de devolución de llamada que pasas, la cual actualiza el DOM a la vista nueva (pero aún no la muestra). Cuando se completa la función de devolución de llamada, el navegador inicia la transición al contenido nuevo.
// Fallback for browsers that don't support this API:
if (!document.startViewTransition) {
updateTheDOMSomehow();
return;
} else {
// With a View Transition:
document.startViewTransition(() => updateTheDOMSomehow());
}
Cómo personalizar la transición
Como viste en el ejemplo anterior, la transición de vista predeterminada atenúa la vista anterior mientras atenúa la vista nueva. Puedes personalizar la transición para que coincida mejor con el estilo de tu sitio aplicando un diseño a los seudoelementos generados por las transiciones de vista.
Puedes especificar la transición de salida con ::view-transition-old()
y la transición de entrada con ::view-transition-new()
. También puedes especificar valores para ambos con ::view-transition-group()
.
En este ejemplo, la vista anterior realizará la transición de salida con la transición slide-out-to-left
y la vista nueva realizará la transición de entrada con la transición slide-in-from-right
. Ambos tendrán una duración de 200 milisegundos.
::view-transition-group(root){
animation-duration: 200ms;
}
::view-transition-old(root) {
animation-name: slide-out-to-left;
}
::view-transition-new(root) {
animation-name: slide-in-from-right;
}
Diferentes transiciones según el contexto
Es posible que desees tener diferentes transiciones según lo que esté haciendo el usuario. Por ejemplo, si hacer clic en un vínculo de tu página principal desliza la vista nueva desde la derecha, esperarías que hacer clic en un vínculo para volver a tu página principal deslice la vista de la página principal desde la izquierda.
Puedes especificar diferentes animaciones con la seudoclase :active-view-transition-type()
.
html:active-view-transition-type(forwards) {
&::view-transition-old(root) {
animation-name: slide-out-to-left;
}
&::view-transition-new(root) {
animation-name: slide-in-from-right;
}
}
Luego, puedes elegir qué tipo de transición de vista usar cuando llames a document.startViewTransition()
.
const direction = next === 'home' ? 'backwards' : 'forwards';
document.startViewTransition({
update: updateTheDOMSomehow,
types: [direction],
});
Transición de elementos específicos
Hasta ahora, solo aplicaste una transición al elemento raíz para que toda la vista cambie. Sin embargo, también puedes usar las transiciones de vista para animar partes específicas de tus páginas.
Por ejemplo, es posible que tengas contenido en la vista anterior que coincida con el contenido de la vista nueva. Puede ser el título del contenido o una imagen. Incluso podría ser una imagen en miniatura en la vista anterior y un video en la vista nueva.
Primero, debes especificar qué elementos realizarán la transición con la propiedad view-transition-name
. Para que las transiciones de vista funcionen, para cada view-transition-name
, debe haber exactamente un elemento antes de que llames a document.startViewTransition()
y exactamente un elemento después de que se complete la devolución de llamada en document.startViewTransition()
.
En este ejemplo, hay un reproductor de música que muestra la portada del álbum, el título y el artista. Una vista alternativa muestra el mismo contenido reorganizado, con la adición de la letra de la canción.
En el ejemplo anterior, hay exactamente uno de cada uno de los elementos con transición en la vista anterior y la nueva, y hasta comparten los mismos selectores. Los elementos en transición parecen moverse entre sus tamaños y posiciones. Las partes de la vista que no tienen transición se desvanecen.
Veamos un ejemplo más complejo. Por ejemplo, la página principal de un blog puede mostrar un titular y una imagen para cada entrada, y estos también están presentes en la vista de página completa de una entrada de blog. Cuando navegas desde la página principal a una publicación específica, es posible que desees que parezca que el título y la imagen se trasladan a su nueva ubicación para proporcionar contexto.
Para hacer esto con el título, debes tener un view-transition-name
en el elemento del título que sea único en la vista anterior, compartido con el elemento del título en la vista nueva y único en la vista nueva. Esto es un desafío, ya que la página principal tiene varios títulos y varias imágenes, y no sabes en cuál hará clic el usuario.
Tienes dos opciones para solucionar este problema. Puedes agregar un view-transition-name
único para cada publicación en la página principal y, luego, hacer coincidir ese nombre en cada publicación de página completa. Puedes generarlos con el ID de una publicación. La otra opción es usar un view-transition-name
genérico, pero solo aplicarlo después de que el usuario haga clic en una publicación y antes de llamar a document.startViewTransition()
.
Diseño de transiciones
Las transiciones de vista son un conjunto de herramientas que puedes usar para guiar a los usuarios y proporcionar sugerencias adicionales sobre la marca o el contexto. Es probable que uses varias técnicas para encontrar las transiciones que funcionan para tu sitio.
Según el efecto que busques, es posible que también debas ajustar los elementos o las animaciones. En el ejemplo anterior, se ajustaron varios estilos para obtener las transiciones fluidas.
El título tiene la regla width: fit-content
, que es un estilo útil cuando se hace la transición de texto que no se ajusta (o tiene el mismo ajuste en la vista anterior y la nueva). De lo contrario, la transición puede ser entre elementos con diferentes anchos, lo que hará que la transición sea menos fluida.
La imagen también tiene una relación de aspecto diferente en la vista anterior y en la nueva. En el ejemplo, se modifican la animación y la propiedad object-fit
para que la transición parezca fluida.
Respetar prefers-reduced-motion
Un motivo común por el que los usuarios solicitan movimiento reducido es que las animaciones de pantalla completa, como las que se pueden lograr con las transiciones de vistas, pueden causar molestias a las personas con trastornos vestibulares del movimiento. Puedes inhabilitar las animaciones con la consulta de medios prefers-reduced-motion
. También puedes proporcionar animaciones alternativas que sean más sutiles, pero que sigan transmitiendo cómo se conectan los elementos.
@media (prefers-reduced-motion) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation: none !important;
}
}
Verifica tus conocimientos
¿Cuál es el nombre del seudoelemento que representa la vista antes de que se llame a document.startViewTransition()
?
::view-transition-previous
::view-transition-prior
::view-transition-old
::view-transition-initial
¿Cuál es la animación predeterminada para una transición de View?
¿Cuál es el view-transition-name
predeterminado de una página?
document
shadow-root
root
body