Animación
El movimiento en una interfaz explica lo que ha ocurrido: de dónde vino un elemento, a dónde fue, si se registró una pulsación. Todo lo que no hace esto es decoración, y la decoración tiene su propio presupuesto pequeño. Esta skill ayuda a gastar ese presupuesto con precisión: sin ella, el modelo lo anima todo con el mismo fundido de entrada.
La skill es autónoma. Si se instalan junto a ella ui-ux (reglas de estilo e interfaz) y front (código y pila), se complementan.
Tres preguntas primero
- ¿Para qué es este movimiento? Retroalimentación de una acción, un vínculo entre estados, llamar la atención sobre algo importante, el carácter de la marca. Si no hay respuesta, no se anima.
- ¿Con qué frecuencia lo verá la persona? El presupuesto depende de la respuesta (siguiente sección).
- ¿Qué existe ya en el proyecto? Mira las duraciones, curvas y librería de animación en uso y continúa en el mismo espíritu. Una librería nueva para un solo efecto es casi siempre un error.
Cuánta animación es adecuada
La regla principal: cuanto más frecuente es la acción, menos animación. Lo que deleita en la primera visualización irrita en la centésima.
| Con qué frecuencia lo ve el usuario | Qué hacer |
|---|---|
| Cientos de veces al día (atajos de teclado, paleta de comandos, cambio de pestañas) | Sin animación |
| Decenas de veces al día (menús, tooltips, hover) | Muy rápida, hasta 150 ms, o sin animación |
| Ocasionalmente (diálogo, panel lateral, notificación) | Una transición normal de 200–300 ms |
| Raramente o una vez (onboarding, pantalla de éxito, primera pantalla de una landing page) | Puede ser expresiva |
Nivel según tipo de proyecto:
- App (se usa a diario): contenida. Estados de control, capas que entran y salen, cambios suaves de diseño. Todo bajo 300 ms. Nada se mueve sin una acción del usuario.
- Escaparate (landing page, sitio web, promoción): notable. Un momento orquestado en la primera pantalla, bloques que se revelan al hacer scroll, detalles vivos al pasar el ratón. El resto, tranquilo.
Un momento expresivo por pantalla, tranquilo en todas partes. Animar todo a la vez es tanto un signo de plantilla como no tener ninguna animación.
No animar: acciones activadas por teclado, cambio de tema, menús contextuales, cualquier cosa que el usuario haga muchas veces seguidas.
Gusto por defecto
El propietario de la skill puede editar esta sección para ajustarla a sus propias preferencias. Las palabras del usuario en la solicitud actual tienen prioridad.
Bienvenido en superficies de escaparate:
- Revelar al hacer scroll — las secciones y objetos grandes aparecen suavemente al desplazarse. Una vez, sin repeticiones.
- Escenas vinculadas al scroll — una sección fijada donde el desplazamiento impulsa la animación y explica algo sobre el producto. Una o dos por página; el scroll en sí sigue siendo normal, nunca se secuestra su velocidad o dirección.
No usar a menos que se pida explícitamente:
- Brillo y bordes con gradiente — contornos brillantes, resplandor neón, fondos con gradiente animado. El énfasis proviene del movimiento y la tipografía, no de la luz.
Librerías: CSS primero; cuando no sea suficiente en React — Motion; GSAP solo para escenas complejas de scroll. Los detalles están en references/tools.md.
El carácter del movimiento es "conectado y preciso".
- Flujos dentro de una app. Las pantallas se funden entre sí en lugar de intercambiarse: un objeto "héroe" viaja a través de cada paso, el texto se convierte en texto mediante un desenfoque, solo cambia lo que cambió, una nueva capa crece desde su origen. Si la tarea tiene una secuencia de pantallas o estados, lee primero
references/continuity.mdy asigna un héroe. - Landing pages y sitios web. Una curva para todo el sitio con un inicio pronunciado y una larga desaceleración suave, sin rebote; el titular se monta palabra por palabra; los objetos grandes aparecen desde un desenfoque; una escena de texto al hacer scroll; todo en CSS. Las recetas con valores exactos están en
references/showcase-recipes.md.
Lo que ambas comparten: desenfoque junto con opacidad como material de una transición, superposición de entrada y salida en lugar de una cola, sin rebote, y una curva consistente. Si el estilo del proyecto requiere un carácter diferente (terminal, retro), consulta la tabla en references/patterns.md.
Duraciones
| Qué | Duración |
|---|---|
| Respuesta a una pulsación, hover, el toggle en sí | 100–150 ms |
| Tooltip, menú desplegable, una entrada pequeña | 150–200 ms |
| Diálogo, panel, hoja | 200–300 ms |
| Contenido que cambia en respuesta a una acción (precio, contador, gráfico) | 300–500 ms |
| Transición de página, un cambio grande de diseño | 300–500 ms |
| Escenas decorativas en superficies de escaparate, sin intervención del usuario | hasta 800–1000 ms |
- La salida es más corta que la entrada aproximadamente en un tercio: lo que se va ya no es interesante.
- Cuanto más largo sea el trayecto y mayor sea el área, más larga será la duración; un elemento pequeño a 400 ms parece lento.
- Cuando las reglas se superponen, gana la más corta. El control en sí siempre responde en 100–150 ms; lo que cambió puede tardar más en terminar, pero el usuario no debe tener que esperar a que termine la animación para volver a actuar.
Curvas y springs
- Entrada — ease-out: un inicio rápido y una parada suave, que se siente receptivo.
- Salida — también ease-out, pero más corta. Algunos sistemas de diseño usan una curva acelerada para las salidas, pero su inicio lento parece un retraso, por lo que no se usa aquí; el propietario de la skill puede cambiar esta regla.
- Movimiento a través de la pantalla de punto a punto — ease-in-out.
- Lineal — solo para movimiento continuo: un indicador giratorio, un marquee, progreso.
Tokens por defecto:
:root {
--ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* curva principal: inicio pronunciado, larga desaceleración */
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
--duration-fast: 160ms; /* respuesta: color, opacidad */
--duration-base: 300ms; /* capas, fondo y sombra de controles */
--duration-slow: 450ms; /* contenido fusionándose */
--duration-reveal: 800ms; /* bloques que aparecen en superficies de escaparate */
}
Una curva para todo el proyecto: cuando cada parte de una transición la usa, se leen como un solo movimiento. Con esta curva, una respuesta puede durar 200–450 ms y seguir sintiéndose instantánea, porque la mayor parte del cambio ocurre en los primeros 100 ms.
Los springs superan a las curvas cuando un gesto impulsa el movimiento o la animación puede interrumpirse a medio camino (arrastrar, una hoja, reordenar una lista): conservan la velocidad y no dan tirones. El rebote es solo para el movimiento y la escala; para el color y la opacidad siempre es cero. El rebote perceptible es adecuado para estilos lúdicos e irrita en herramientas de trabajo.
Reglas de ejecución
- Animar
transformyopacity. El ancho, alto, márgenes y posición provocan recálculos de diseño y causan tirones. Para cambiar el tamaño usascale, la técnica FLIP o la animación de diseño de una librería. - El desenfoque es la excepción permitida.
filter: blur()hasta 12px junto con opacidad es el material característico de una transición, pero cuesta más: aplícalo a bloques pequeños (un titular, una figura, un icono, una tarjeta), nunca a una pantalla completa, y pruébalo en un teléfono. - Entrada y salida se superponen. Lo que sale y lo que llega coexisten durante el 30–50% de la duración. Una cola de "primero desapareció, luego apareció" rompe la conexión y duplica el tiempo.
- Solo se mueve la diferencia. Lo que no cambió (dígitos, palabras, iconos) permanece en su sitio.
- Nunca empezar desde
scale(0). Nada en la vida aparece desde un punto: empieza en 0.9–0.96 junto con opacidad. transform-originse sitúa en el origen. Un menú crece desde su botón, no desde el centro.- Pulsación:
scale(0.97)en:activeda la sensación de un botón físico. - Interrumpibilidad. Construye el movimiento interactivo con
transition, no con@keyframes: una transición puede invertirse a mitad de camino, las keyframes no. - Roles primero, sincronización después. Cuando varios elementos se mueven en respuesta a un evento, asigna un único líder; el resto son soporte, decoración o estáticos. Dos líderes son un problema de diseño, no de animación.
- Una entrada por contenedor. Si el panel se deslizó hacia adentro, su contenido ya está allí: no añadas un escalonamiento de hijos sobre la entrada del padre.
- Lo que sale libera su espacio inmediatamente, para que los vecinos se cierren mientras se desvanece, no después.
- La salida refleja la entrada y ocurre toda a la vez. Lo que entró por la derecha sale por la derecha; un grupo desaparece simultáneamente, sin escalonamiento inverso.
- La dirección sigue el significado: "adelante" entra por la derecha, "atrás" por la izquierda.
- Escalonamiento: un paso de 30–80 ms entre elementos, toda la cascada no más de 300–400 ms; después del sexto o séptimo elemento, el resto aparece junto. En la primera pantalla de un escaparate, el paso puede llegar a 100–150 ms.
- Los gestos usan springs y nunca bloquean. El elemento sigue el dedo uno a uno, puede agarrarse a medio camino, y después de soltarlo recoge la velocidad del gesto. Rebote solo después de un lanzamiento.
- Tooltips: un retraso antes del primero; los siguientes en el mismo grupo aparecen inmediatamente y sin animación.
- Revelar al hacer scroll ocurre una vez. Un bloque que se oculta y reaparece en cada paso es agotador.
- La página está completa en reposo. El contenido no debe depender de si se ejecutó un script: el estado inicial oculto se establece solo junto con la animación habilitada, nunca en los estilos base. De lo contrario, cuando un script falla, en previsualizaciones y capturas de pantalla, el usuario ve una pantalla vacía.
- El hover cambia una propiedad, no escala, elevación y sombra a la vez.
will-change— con moderación y solo durante la duración de la animación, no en todo.
Accesibilidad
Esto no es opcional: el movimiento en pantalla causa mareos y náuseas a algunas personas.
prefers-reduced-motion: reduce: elimina movimiento, escala, rotación, paralaje y reproducción automática; mantén el cambio suave de opacidad y color. Apagar todo priva a la persona de retroalimentación. El enfoque más fiable es declarar el movimiento solo donde está permitido:
.card { transition: opacity var(--duration-base) var(--ease-out), background-color var(--duration-fast); }
@media (prefers-reduced-motion: no-preference) {
.card { transition-property: opacity, background-color, transform; }
.card:hover { transform: translateY(-2px); }
}
- Cualquier cosa que se mueva sola durante más de 5 segundos (un marquee, un carrusel, video de fondo) tiene un botón de pausa, un requisito de WCAG 2.2.2.
- Nada parpadea más de tres veces por segundo.
- Mantén el movimiento en un área grande (paralaje, escalado de fondo) con una amplitud pequeña.
- El texto animado sigue siendo legible para un lector de pantalla: una división por caracteres recibe un
aria-labelcon la frase completa, y las piezas recibenaria-hidden.
Verificación
- Observa la animación en un navegador, no solo en el código; si no puedes, informa al usuario que no se verificó en vivo.
- Redúcela 4–10× en las herramientas de desarrollador: los tirones, un origen de crecimiento incorrecto y propiedades innecesarias se vuelven visibles.
- Presiona rápidamente varias veces seguidas: la animación debe interrumpirse e invertirse, no acumularse en una cola.
- Activa "reduce motion" en el sistema y asegúrate de que la interfaz sigue funcionando y siendo comprensible.
- Una captura de pantalla tomada justo después de hacer scroll puede mostrar un espacio vacío donde un bloque aún no ha aparecido: una razón para comprobar la regla "la página está completa en reposo".
Modo de revisión
Cuando se pida evaluar o corregir una animación existente, presenta los hallazgos en una tabla:
| Dónde | Antes | Después | Por qué |
|---|---|---|---|
Modal.tsx:18 | scale(0) → 1, 500 ms, ease-in | scale(0.96) + opacidad, 220 ms, ease-out | aparece desde un punto y va lento |
Archivos de referencia
references/continuity.md— animación conectada: el héroe de un flujo, pantallas que se funden entre sí, números que cambian dígito a dígito, colapso al hacer scroll; las técnicas y cómo construirlas en la web. Léelo para cualquier secuencia de pantallas o estados.references/choreography.md— un grupo de elementos que reaccionan a un evento: roles (líder, soporte, decoración, estático), relaciones dentro de un par (juntos, superposición, secuencia, arrastre), escalonamientos, dirección, salida, interrupción. Léelo siempre que se mueva más de un elemento.references/gestures.md— todo lo que se arrastra, desliza y lanza: seguimiento del dedo, interrumpibilidad, springs, transferencia de velocidad, proyección de impulso, límites suaves. Léelo para hojas, carruseles, deslizadores, arrastrar y soltar.references/showcase-recipes.md— recetas para landing pages con valores exactos: un titular palabra por palabra, aparición desde un desenfoque, un subrayado dibujado, una cascada de tarjetas, texto al hacer scroll. Léelo para la primera pantalla y secciones de un sitio.references/patterns.md— un catálogo de técnicas: microinteracciones, entradas, cambios numéricos, scroll, transiciones de página, texto; cuándo funciona cada una y cuándo perjudica; el carácter del movimiento según el estilo.references/tools.md— una escalera de herramientas desde CSS hasta GSAP con ejemplos de código y reglas de selección.