Motion design: microinteracciones con sentido
Objetivos de este capítulo
- Ajustar duración, curva y propiedad de cada animación
- Coreografiar las apariciones y las transiciones al hacer scroll
- Respetar el rendimiento y prefers-reduced-motion
Una página perfecta, pero congelada
La landing de Sereno está ya tipografiada, con tema claro y oscuro, accesible. El cliente la hace desfilar en silencio y suelta: « Es muy bonita. Pero está… inmóvil. Parece un cartel. » El director de Studio Mango traduce: falta el motion — esa capa de movimiento que hace que una interfaz parezca viva y responda bajo los dedos. El capítulo 5 puso la regla (cortas, suaves, significativas); hoy construyes el sistema de movimiento completo, con el mismo rigor que para los colores y la tipografía.
Porque ese es el punto clave: el motion se concibe en tokens y reglas, no en efectos añadidos sobre la marcha. Una interfaz donde cada elemento se mueve a su propia velocidad con su propia curva parece chapucera — exactamente como una página con espaciados aleatorios. Un pequeño número de duraciones, una o dos curvas firma, reglas de uso: eso es lo que vas a entregar.
El movimiento es un lenguaje funcional
Antes de los ajustes, el porqué. Una animación bien concebida cumple uno de tres roles. El feedback: confirmar que una acción ha sido percibida — el botón que se hunde ligeramente al clic dice « te he oído ». La orientación: mostrar de dónde viene y adónde va un elemento — el panel que se desliza desde la derecha indica que se cerrará hacia la derecha. La continuidad: enlazar dos estados de una interfaz para que el cambio no sea un salto brutal — la tarjeta que se expande con suavidad en lugar de una modal que surge de la nada.
Toda animación que no cumple ninguno de esos roles es decorativa — ruido. Para una app de meditación, el criterio es aún más estricto: cada movimiento debe apaciguar, jamás distraer. Pregúntate por cada animación: « ¿qué le dice al usuario? ». Si la respuesta es « nada, pero es bonita », suprímela. Es la versión motion de la caza de lo genérico.
Los tres ajustes: duración, curva, propiedad
Primera decisión: la duración, proporcional a la amplitud del cambio. Los micro feedbacks (hover, focus, casilla marcada) viven entre 100 y 200 ms — más corto parece instantáneo, más largo parece blando. Las transiciones medias (aparición de una tarjeta, despliegue de un acordeón) entre 200 y 300 ms. Los grandes movimientos (panel lateral, cambio de página) entre 300 y 500 ms — más allá, el usuario espera a la interfaz, y la espera repetida se convierte en irritación.
Segunda decisión: la curva de aceleración (easing). La regla física: lo que entra en pantalla decelera (ease-out — el elemento llega rápido y se posa con suavidad), lo que sale acelera (ease-in — se escapa), lo que se desplaza en el sitio hace ambas cosas (ease-in-out). El linear queda reservado a las rotaciones continuas tipo spinner. Y para dar una firma a Sereno, se define una curva cubic-bezier propia, suave y ligeramente amortiguada, usada en todas partes — es el equivalente motion de la fuente de títulos.
:root {
/* Tokens de movimiento — el sistema, no efectos aislados */
--duration-fast: 150ms; /* micro feedback: hover, focus */
--duration-base: 250ms; /* transiciones medias: tarjetas, acordeones */
--duration-slow: 400ms; /* grandes movimientos: paneles, páginas */
--ease-out-soft: cubic-bezier(0.25, 0.8, 0.35, 1); /* la firma Sereno */
--ease-in-soft: cubic-bezier(0.55, 0, 0.7, 0.4);
}
.btn {
transition:
background-color var(--duration-fast) var(--ease-out-soft),
transform var(--duration-fast) var(--ease-out-soft),
box-shadow var(--duration-fast) var(--ease-out-soft);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(0.98); }--ease-out-soft) y prohíbe los easings improvisados en los prompts, exactamente como prohíbes los colores en duro.Rendimiento: anima solo transform y opacity
Tercera decisión, la más técnica: la propiedad animada. No todas las propiedades CSS valen lo mismo. Animar width, height, top o margin obliga al navegador a recalcular la maquetación de toda la zona en cada fotograma — en un teléfono medio, la animación da tirones. Animar transform (traslación, escala, rotación) y opacity lo procesa directamente el procesador gráfico: fluido a 60 fotogramas por segundo, incluso en hardware modesto.
La traducción práctica: un elemento que « sube » al hover usa transform: translateY(-2px), jamás top: -2px. Un panel que se abre se desliza con translateX, no cambia su width. Una aparición combina opacity y una pequeña traslación. Añade esta restricción a todos tus prompts de motion — es una de esas exigencias que la IA respeta perfectamente cuando se formula, y olvida una de cada dos veces si no.
will-change: útil puntualmente para preparar una animación pesada, consume memoria si se pone en todas partes « por precaución ». La regla: añadirlo solo si una animación da tirones de verdad, y retirarlo después de la animación.Coreografía: ordenar las apariciones
Una página no aparece de un bloque: se cuenta. La coreografía consiste en ordenar las apariciones según la jerarquía de lectura: el título primero, el subtítulo después, el CTA al final — cada uno desfasado de 50 a 80 ms respecto al anterior. Ese desfase (el « stagger ») es lo bastante corto para que el conjunto parezca fluido, y lo bastante largo para que el ojo siga el hilo. Las tres tarjetas de beneficios aparecen en cascada izquierda-derecha, no todas a la vez.
flowchart LR L["Carga de la sección"] --> T["Título: aparición inmediata"] T --> ST["Subtítulo: desfase de 60 ms"] ST --> CTA["CTA: desfase de 120 ms"] CTA --> C1["Tarjeta 1"] C1 --> C2["Tarjeta 2: más 70 ms"] C2 --> C3["Tarjeta 3: más 140 ms"]
Apariciones al hacer scroll, con sobriedad
El gran clásico de las landing pages: las secciones que se revelan con suavidad a medida que se desplaza la página. Bien dosificado, el efecto da ritmo a la lectura; sobredosificado, transforma la página en parque de atracciones. Las reglas de sobriedad: una distancia de desplazamiento corta (12 a 16 px, no 100), una aparición única (el elemento permanece visible una vez revelado, no vuelve a ejecutar la animación a cada paso), y un solo tipo de efecto para toda la página — fundido + ligera subida, punto. Nada de zoom aquí, rotación allá, rebote más allá.
/* CSS: el estado inicial y el estado revelado */
.reveal {
opacity: 0;
transform: translateY(14px);
transition: opacity var(--duration-slow) var(--ease-out-soft),
transform var(--duration-slow) var(--ease-out-soft);
}
.reveal.is-visible { opacity: 1; transform: none; }// JS: IntersectionObserver — revela una sola vez
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
observer.unobserve(entry.target); // una sola vez
}
}
}, { threshold: 0.15 });
document.querySelectorAll('.reveal').forEach((el) => observer.observe(el));Añade un sistema de motion completo a la landing de Sereno (código adjunto): - tokens: --duration-fast 150ms, --duration-base 250ms, --duration-slow 400ms, curva firma cubic-bezier(0.25, 0.8, 0.35, 1) - micro feedbacks: hover y active en botones, tarjetas y enlaces (transform + sombra, jamás top/width) - coreografía de la hero: título, luego subtítulo (+60ms), luego CTA (+120ms), en fundido + translateY(14px) - apariciones al hacer scroll: secciones en fundido + subida de 14px, una sola vez, vía IntersectionObserver - RESTRICCIONES: anima solo transform y opacity; ninguna animación de más de 500ms; ningún rebote ni efecto elástico - añade el bloque @media (prefers-reduced-motion: reduce) que desactiva traslaciones y stagger conservando simples fundidos rápidos Da el CSS y el JS separados, comentados.
prefers-reduced-motion: no negociable
Una parte de los usuarios sufre trastornos vestibulares: los movimientos de interfaz — parallax, deslizamientos amplios, zooms — les causan vértigos y náuseas reales. Otros simplemente prefieren una interfaz tranquila. Todos pueden activar « reducir las animaciones » en su sistema, y tu CSS debe escucharlo vía la media query prefers-reduced-motion: reduce. Reducir no significa romperlo todo: se sustituyen las traslaciones por simples fundidos cortos, y se suprimen las animaciones puramente decorativas. La interfaz sigue viva, deja de moverse en el espacio.
@media (prefers-reduced-motion: reduce) {
.reveal {
transform: none; /* no más desplazamiento espacial */
transition: opacity 120ms ease; /* un simple fundido corto */
}
.btn:hover, .btn:active { transform: none; }
}Para una app de meditación, la ironía sería cruel: marear al usuario que vino a buscar la calma. Integra la media query desde el primer prompt de motion (como arriba), no como parche de última hora — y añade este punto a tu lista de verificación de entrega, al mismo nivel que los contrastes.
Cuándo no animar
Auditoría de motion de la landing Sereno (código adjunto). Elabora una tabla exhaustiva de cada animación: - elemento afectado, disparador, duración, curva, propiedades animadas - su rol: feedback, orientación o continuidad — escribe « NINGUNO » si es puramente decorativa - conformidad: ¿propiedades limitadas a transform/opacity? ¿duración por debajo de 500 ms? ¿comportamiento definido bajo prefers-reduced-motion? Después: 1. lista las animaciones a SUPRIMIR (rol NINGUNO) con una frase de justificación 2. lista las no conformidades técnicas y su corrección 3. verifica que todas las duraciones y curvas provienen de los tokens --duration-* y --ease-*, y señala todo valor en duro
Termina con el inventario crítico: pide a la IA la lista de todas las animaciones de la página con su duración, su propiedad y su rol (feedback, orientación, continuidad). Toda línea cuyo rol quede vacío es candidata a la supresión. Verás casi siempre el mismo resultado: la página final cuenta con menos animaciones que la versión intermedia, pero cada una es justa. El motion premium se parece al montaje de una buena película — no se notan los cortes, solo se siente que todo fluye. El cliente no dirá « bonitas animaciones »; dirá « es relajante », y esa es exactamente la misión.
Contexto
« Está inmóvil », dijo el cliente. Tienes una tarde para añadir la capa de movimiento a la landing de Sereno: micro feedbacks, coreografía de la hero, revelaciones al hacer scroll — todo fluido en un teléfono de gama de entrada y respetuoso con prefers-reduced-motion. El director será intratable en un punto: ni un solo movimiento gratuito.
Instrucciones
- Define tus tokens de motion: tres duraciones (150/250/400 ms) y una curva firma cubic-bezier, añadidos al design system.
- Añade los micro feedbacks a botones, tarjetas y enlaces — únicamente transform y opacity, transiciones de 150 ms.
- Coreografía la hero: título, subtítulo, CTA en cascada con un stagger de 60 ms, en fundido + subida de 14 px.
- Implanta las revelaciones al hacer scroll con IntersectionObserver: un solo tipo de efecto, una sola vez por elemento.
- Añade el bloque prefers-reduced-motion que sustituye todo desplazamiento por un fundido corto, y pruébalo activando la opción en tu sistema.
- Pide el inventario crítico: lista de cada animación con su rol (feedback, orientación, continuidad) — suprime toda línea sin rol.
En resumen
- El motion se concibe en sistema: tokens de duraciones, curva firma, reglas de uso — no en efectos aislados.
- Cada animación cumple un rol: feedback, orientación o continuidad — si no, es ruido a suprimir.
- Duraciones: 100-200 ms para los micro feedbacks, 200-300 ms para las transiciones, 300-500 ms para los grandes movimientos.
- Ease-out para lo que entra, ease-in para lo que sale, ease-in-out para lo que se desplaza; linear reservado a las rotaciones continuas.
- Solo se animan transform y opacity: las demás propiedades hacen dar tirones a los teléfonos modestos.
- La coreografía sigue la jerarquía de lectura con un stagger de 50-80 ms; al hacer scroll: un solo efecto, una sola vez, 12-16 px.
- prefers-reduced-motion no es negociable: sustituir los desplazamientos por fundidos cortos, desde el primer prompt.
Quiz — comprueba tu comprensión
1. ¿Cuáles son los tres roles legítimos de una animación de interfaz?
2. ¿Qué duración conviene a un micro feedback de hover?
3. ¿Por qué animar solo transform y opacity?
4. ¿Qué curva de aceleración para un elemento que entra en pantalla?
5. ¿Qué debe hacer el bloque prefers-reduced-motion: reduce?
6. ¿Qué es un « stagger » en una coreografía de aparición?