IMPLEMENTAR animaciones suaves con sensación nativa usando la API View Transition de React (`<ViewTransition>`, `addTransitionType` y pseudo-elementos CSS de view transition). Usar para transiciones de página, cambios de ruta, animaciones de elementos compartidos, animaciones de entrada/salida, reorden de listas, navegación direccional. Soporte de navegador: Chromium 111+, Firefox 144+, Safari 18.2+. Degradación elegante en navegadores sin soporte. Nunca llamar `document.startViewTransition` directamente, usar el componente `<ViewTransition>`.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
IMPLEMENTAR animaciones suaves con sensación nativa usando la API View Transition de React (`<ViewTransition>`, `addTransitionType` y pseudo-elementos CSS de view transition). Usar para transiciones de página, cambios de ruta, animaciones de elementos compartidos, animaciones de entrada/salida, reorden de listas, navegación direccional. Soporte de navegador: Chromium 111+, Firefox 144+, Safari 18.2+. Degradación elegante en navegadores sin soporte. Nunca llamar `document.startViewTransition` directamente, usar el componente `<ViewTransition>`.
SIEMPRE establecer default="none", previene fundidos cruzados no deseados
SIEMPRE etiquetar la navegación con addTransitionType('nav-forward') / nav-back
Colocar en componentes de página, NO en layouts
Paso 5: Añadir Revelaciones de Contenido Suspense (Prioridad 2)
// Revelación de contenido, separada de transiciones de navegación
<ViewTransition enter="fade-in"default="none">
<Suspensefallback={<Skeleton />}>
<Content /></Suspense>
</ViewTransition>
Suspense + navegación coexisten: Se disparan en momentos diferentes. La navegación dispara enter/exit con clave de tipo. La resolución de Suspense dispara enter/exit con props de cadena. default="none" previene interferencia.
1. SIEMPRE establecer default="none" en CADA ViewTransition, previene fundido cruzado en Suspense/resync
2. SIEMPRE usar nombres únicos para elementos compartidos, nombres duplicados rompen los morphs
3. SIEMPRE emparejar enter con exit, animaciones asimétricas confunden a los usuarios
4. NUNCA llamar document.startViewTransition, usar componente <ViewTransition>
5. NUNCA escribir keyframes de animación personalizados, usar recetas CSS de references/
6. SIEMPRE incluir CSS de movimiento reducido en la hoja de estilos global
7. SIEMPRE mantener <ViewTransition> como el wrapper más externo, enter/exit se activan solo cuando VT es el primer nodo DOM
LIMITACIONES CONOCIDAS
- router.back() y atrás/adelante del navegador NO disparan view transitions
→ Usar router.push() con URL explícita en su lugar
- VT anidados enter/exit: exit del padre suprime enter/exit del hijo
→ Solo el VT más externo se anima durante las salidas de página
- Tipos disponibles durante navegación pero NO durante revelaciones Suspense
→ Usar mapas de tipo para enter/exit de página, cadenas simples para Suspense
VALIDAR: Puertas de Calidad
Elementos compartidos usan nombres ÚNICOS (photo-${id}, NUNCA photo)
Transiciones direccionales usan claves de tipo (addTransitionType('nav-forward'))
default="none" en CADA ViewTransition, previene fundidos cruzados no deseados
CSS de movimiento reducido incluido en hoja de estilos global (copiar de references/css-recipes.md)
Revelaciones Suspense usan props de cadena simples (NO mapas con clave de tipo), navegación y carga no interfieren
NUNCA llama a document.startViewTransition directamente, siempre usa <ViewTransition>
experimental: { viewTransition: true } habilitado en next.config.ts
Navegadores sin soporte omiten animaciones elegantemente, cero rotura de diseño
ANTIPATRONES: SIEMPRE Evitar
Antipatrón
Por qué está mal
Solución
document.startViewTransition()
API cruda evade el ciclo de vida de React
Usar componente <ViewTransition>
Sin default="none"
Cada resolución de Suspense dispara fundido cruzado