Orquesta el desplazamiento magnético, las transiciones de estado animadas por el navegador y el respeto riguroso a prefers-reduced-motion.
Abrir esta lección en KodokonEl scroll snap involucra a dos actores: el contenedor define un snapport (su área visible, encogida por scroll-padding) y una estrategia mediante scroll-snap-type - proximity solo ajusta cerca de un punto de anclaje, mientras que mandatory garantiza que siempre aterrizas en uno, incluso tras un desplazamiento programático. Los hijos declaran su área de alineación con scroll-snap-align (ajustable mediante scroll-margin). Una sutileza poco conocida: durante un deslizamiento rápido, el navegador puede legítimamente saltarse varios puntos de anclaje; scroll-snap-stop: always lo obliga a detenerse en cada uno, esencial para un carrusel estilo stories.
.carousel {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-padding-inline: 1rem;
}
.carousel > article {
flex: 0 0 80%;
scroll-snap-align: center;
scroll-snap-stop: always;
}La API View Transitions anima un cambio de estado del DOM sin ninguna biblioteca. document.startViewTransition(callback) captura una instantánea visual del estado actual, ejecuta tu callback (que muta el DOM) y luego anima entre el estado antiguo y el nuevo. Por dentro, el navegador construye un árbol de pseudoelementos sobre la página: ::view-transition contiene elementos ::view-transition-group, cada uno con un ::view-transition-old (la instantánea, contenido reemplazado comparable a una imagen) y un ::view-transition-new (la representación en vivo). Por defecto: un fundido cruzado. La página es no interactiva durante la transición.
function applyUpdate(updateDom) {
if (!document.startViewTransition) {
updateDom();
return;
}
document.startViewTransition(() => updateDom());
}El verdadero poder viene de view-transition-name: un elemento nombrado se extrae a su propio grupo de transición. Si existe un elemento con el mismo nombre antes y después, el navegador interpola automáticamente la posición y el tamaño entre ambos - el efecto de morfismo de una miniatura a su vista a pantalla completa, sin una sola línea de JavaScript de animación. Cada nombre debe ser único en la página en cualquier momento dado, o la transición se abandona. Los pseudoelementos se estilizan con animaciones CSS corrientes.
.hero-thumb { view-transition-name: hero; }
::view-transition-old(hero),
::view-transition-new(hero) {
animation-duration: 0.4s;
animation-timing-function: ease-in-out;
}Queda la obligación de accesibilidad: prefers-reduced-motion: reduce señala a un usuario sensible al movimiento (trastornos vestibulares, migrañas). Reducir no significa eliminar: un fundido de opacidad sigue siendo aceptable; son los grandes movimientos, los zooms y los efectos de parallax los que deben neutralizarse. Ya conoces la sobrescritura global defensiva en CSS (duraciones casi nulas, tratada en el módulo anterior); las view transitions añaden un segundo frente: del lado de JavaScript, consulta window.matchMedia("(prefers-reduced-motion: reduce)") antes de lanzar una transición o un desplazamiento animado.
const reduceMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)'
).matches;
if (reduceMotion || !document.startViewTransition) {
updateDom();
} else {
document.startViewTransition(() => updateDom());
}