Kodokon kodokon.com

Transiciones y animaciones: @keyframes, transform, temporización

Anima en el compositor con transform y opacity, estructura tus @keyframes y respeta las preferencias de movimiento de los usuarios.

10 min · 3 preguntas

Abrir esta lección en Kodokon

Antes de elegir qué animar, recuerda el pipeline de renderizado: layout (geometría), paint (píxeles), composite (ensamblaje de capas en la GPU). Animar width o top provoca un layout en cada fotograma, a menudo seguido de un paint: esa es la receta del tirón por debajo de los 60 fps. transform y opacity se gestionan directamente en el compositor, sin volver a pasar por las dos primeras etapas. La regla profesional: anima solo esas dos propiedades siempre que sea posible, y simula el resto (translate en vez de top, scale en vez de width).

CSS
.button {
  transform: translateY(0);
  transition:
    transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1),
    opacity 0.15s ease-out;
}

.button:hover {
  transform: translateY(-2px);
}

.button:active {
  transform: translateY(0) scale(0.97);
}
Una transición amigable con el compositor y una curva personalizada

Cuando una transición ya no basta (pasos intermedios, bucles, inicio automático), pasa a @keyframes. Dos ajustes marcan la diferencia entre una animación limpia y un fallo visual: animation-fill-mode controla el estado antes del inicio (backwards aplica el primer fotograma clave durante el retardo) y después del final (forwards congela el último); both combina ambos. Ten en cuenta también que la función de temporización se aplica entre cada par de fotogramas clave, no sobre la duración total: puedes redefinirla dentro de un fotograma clave.

CSS
@keyframes slide-in {
  from {
    transform: translateX(-100%);
    opacity: 0;
  }
  70% {
    transform: translateX(8px);
    opacity: 1;
  }
  to {
    transform: translateX(0);
  }
}

.toast {
  animation: slide-in 0.35s ease-out both;
}
Una entrada con un ligero rebase

Dos herramientas complementarias que conviene conocer. will-change: transform promueve el elemento a su propia capa antes de la animación, evitando un rasterizado tardío; pero cada capa cuesta memoria de GPU, así que aplícalo justo antes de la animación y quítalo después, nunca como un estilo permanente en decenas de elementos. steps(n) reemplaza la interpolación continua por saltos discretos: esencial para sprites, cursores tipo máquina de escribir o relojes.

CSS
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
Respetar prefers-reduced-motion

Prueba de conocimientos

Comprueba que has retenido los puntos clave de esta lección.

  1. ¿Por qué preferir transform: translateX(100px) en lugar de left: 100px para un desplazamiento animado?
    • transform tiene mejor soporte en navegadores antiguos
    • transform lo gestiona el compositor sin recalcular el layout en cada fotograma
    • left solo funciona en elementos posicionados de forma absoluta, transform funciona en todas partes
    • transform acepta valores negativos, a diferencia de left
  2. ¿Qué hace animation-fill-mode: both?
    • La animación se reproduce hacia adelante y luego en reversa
    • La animación se aplica al elemento y a sus descendientes
    • Los estilos del primer fotograma clave se aplican durante el retardo, y los del último persisten tras el final
  3. ¿Cuál es el uso correcto de will-change?
    • Aplicarlo globalmente en * para acelerar toda la página
    • Añadirlo justo antes de una animación costosa y quitarlo después
    • Combinarlo siempre con transform: translateZ(0)
    • Usarlo en lugar de transition para microinteracciones