Por qué el movimiento es importante
El movimiento es comunicación. Un botón que hace una transición suave hacia su estado presionado, un panel que se desliza al entrar en vista y una lista que se reordena fluidamente le indican al usuario qué acaba de suceder. Cuando se hace bien, el movimiento hace que una interfaz se sienta responsiva y pulida. Cuando se hace mal, distrae y frustra.
CSS te ofrece tres herramientas: transitions para cambios de estado, keyframes para secuencias y transforms para el movimiento. Domina estas tres y rara vez necesitarás JavaScript para las animaciones cotidianas.
Transiciones
Una transición interpola suavemente entre dos estados y se ejecuta cuando cambia una propiedad.
/* button.css */
.button {
background: #2563eb;
transform: translateZ(0);
transition: background-color 150ms ease, transform 150ms ease;
}
.button:hover {
background: #3b82f6;
transform: translateY(-1px);
}
.button:active {
transform: translateY(0);
}
La sintaxis abreviada incluye la propiedad, la duración, la función de temporización y un retraso opcional. Las transiciones necesitan un disparador: :hover, :focus, :checked, un cambio de clase mediante JavaScript o una media query. Mantén las duraciones cortas; generalmente, entre 150 y 300 milisegundos es suficiente para proporcionar feedback.
Transforms
Los transforms cambian la apariencia de un elemento sin afectar el diseño (layout) de los demás, razón por la cual son económicos de animar.
/* transform.css */
.move { transform: translateX(24px); }
.grow { transform: scale(1.1); }
.turn { transform: rotate(45deg); }
.skew { transform: skewX(-10deg); }
.combo {
transform: translateY(-4px) scale(1.02) rotate(-1deg);
}
translate, scale y rotate pueden ejecutarse en el compositor, por lo que se mantienen fluidos incluso bajo carga. En cambio, animar width, height, top o margin obliga al navegador a recalcular el layout en cada frame.
Keyframes
Para animaciones de varios pasos o en bucle, utiliza @keyframes y animation.
/* spinner.css */
@keyframes spin {
to { transform: rotate(360deg); }
}
.spinner {
animation: spin 800ms linear infinite;
}
@keyframes fade-up {
from { opacity: 0; transform: translateY(12px); }
to { opacity: 1; transform: translateY(0); }
}
.enter {
animation: fade-up 300ms ease-out both;
}
El shorthand animation define el nombre, la duración, el timing, el retraso, el número de iteraciones, la dirección y el fill mode. both es muy útil para animaciones de entrada ya que aplica los estados del primer y último keyframe.
Funciones de temporización (Timing functions)
La función de temporización controla la sensación del movimiento. El easing es lo que hace que el movimiento se vea natural en lugar de mecánico.
/* easing.css */
.linear { transition-timing-function: linear; }
.ease-out { transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1); }
.bounce { transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); }
- ease-out para elementos que entran en pantalla, para que desaceleren.
- ease-in para elementos que salen.
- ease-in-out para movimientos entre dos estados visibles.
- steps() para efectos similares a fotogramas, como el efecto de escritura o animaciones de sprites.
Rendimiento
La regla es sencilla: anima transform y opacity. Estos pueden ser gestionados por el compositor, omitiendo el layout y el paint. Cualquier cosa que cambie la geometría dispara el layout, y cualquier cosa que cambie el color o la sombra dispara el paint.
/* hint.css */
.animated {
will-change: transform;
}
will-change indica que un elemento está a punto de animarse, para que el navegador pueda promoverlo a su propia capa. Úsalo con moderación y elimínalo una vez que la animación termine; demasiadas capas promovidas desperdician memoria. Consulta la guía de Browsers & Rendering para entender el porqué.
Accesibilidad y movimiento reducido
Algunos usuarios experimentan mareos o náuseas debido al movimiento, y el sistema operativo expone esa preferencia.
/* reduced.css */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
Una regla general como esta es una base segura. Para un enfoque más detallado, sustituye los movimientos amplios por un simple desvanecimiento (fade). Nunca transmitas significados basándote únicamente en el movimiento.
View transitions
La View Transitions API permite animar la transición entre dos estados del DOM o páginas de forma nativa.
// navigate.js
document.startViewTransition(() => {
updateTheDOM();
});
El navegador toma una captura de los estados antiguo y nuevo y anima la transición entre ellos, permitiéndote controlar el efecto mediante pseudo-elementos de CSS. Es ideal para la navegación entre páginas y el reordenamiento de listas. Asegúrate de proporcionar un fallback sencillo para los navegadores que no sean compatibles.
Patrones
- Feedback de hover y focus. Transiciones cortas de color y transform.
- Animaciones de entrada. Fade y slide in con el fill mode
both. - Listas escalonadas (staggered). Retraso ligero en cada elemento, configurado frecuentemente con una variable CSS y estilos inline.
- Skeletons y spinners. Keyframes en bucle para indicar la carga.
- Accordions y drawers. Transición de altura mediante
grid-template-rowsdesde0frhasta1fr, lo que permite una animación fluida.
Mejores prácticas
- Anima
transformyopacity; evita las propiedades de layout. - Mantén las duraciones cortas: entre 150 y 300ms para feedback, y más largas para dar énfasis.
- Usa
ease-outpara las entradas yease-inpara las salidas. - Respeta
prefers-reduced-motion. - Usa
will-changecon moderación y limpia el estado después de animar. - Prefiere CSS para casos sencillos y JavaScript para secuencias complejas.
- Haz pruebas en dispositivos de gama baja, no solo en un escritorio rápido.
Errores comunes
- Animar el width, height o top, lo que provoca jank.
- Dejar
will-changeactivado permanentemente, desperdiciando memoria. - Animaciones largas y lentas que hacen que la UI se sienta pesada.
- Ignorar las preferencias de reducción de movimiento (reduced-motion).
- Movimientos infinitos que distraen del contenido.
- Depender de las animaciones para transmitir información esencial.
Próximos pasos
El movimiento en CSS cubre la mayoría de las necesidades de las interfaces. Cuando busques líneas de tiempo, narrativas basadas en el scroll o un control preciso, pasa a la guía de Animación Avanzada. Comprende el coste computacional con Browsers & Rendering, mantén la velocidad con Web Performance y comienza desde los fundamentos de CSS.