Menu

Transition en CSS: propiedad, duración, curva y retraso

Una transición CSS anima una propiedad de su valor anterior al nuevo cuando cambia, por ejemplo en hover. Aprende la abreviatura transition, todas las funciones de tiempo lado a lado, qué se puede animar y qué no, el truco para height: auto y el movimiento reducido.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Una transición en un ejemplo

Una transición le dice al navegador: cuando cambie esta propiedad, anímala durante este tiempo en lugar de cambiarla de golpe. Ponla en la regla normal del elemento, no solo en :hover:

Pasa el mouse por el primer botón: su color se funde a verde y sube 4px en 0.4 segundos, y al alejar el puntero se reproduce la misma transición al revés. El segundo botón tiene transition: none y cambia al instante. Los usuarios de teclado obtienen el mismo efecto con :focus-visible.

La abreviatura transition

transition: background-color 0.3s ease-in-out 0.1s;
/*          property         duration timing    delay */
Propiedad largaQué definePor defecto
transition-propertyqué propiedades se animan (all, o una lista)all
transition-durationcuánto dura, en s o ms0s
transition-timing-functionla curva de velocidadease
transition-delaycuánto esperar antes de empezar (puede ser negativo)0s

La duración por defecto es 0s, y por eso nada se anima hasta que defines una. En la abreviatura, el primer tiempo siempre es la duración y el segundo el retraso. Para configuraciones distintas por propiedad, sepáralas con comas:

.card {
  transition: transform 0.2s ease-out, box-shadow 0.4s ease-out;
}

Funciones de tiempo lado a lado

La función de tiempo decide cómo cambia la velocidad durante la transición. Presiona Play y las siete barras recorren la misma distancia en los mismos 1.5 segundos:

Función de tiempoSe siente como
linearvelocidad constante, mecánica
ease (por defecto)arranque rápido, frenado suave
ease-inarranque lento, final rápido: bueno para cosas que salen
ease-outarranque rápido, final lento: bueno para cosas que llegan
ease-in-outlenta en los dos extremos
cubic-bezier(x1, y1, x2, y2)tu propia curva; una y mayor que 1 se pasa y vuelve a asentarse
steps(n)salta en n pasos iguales, sin fotogramas intermedios

Para efectos hover y menús, ease-out con una duración de entre 150ms y 300ms se siente ágil.

Qué se puede animar con transition

Se pueden animar las propiedades que tienen valores intermedios: colores, longitudes (width, padding, margin), opacity, transform, box-shadow, border-radius, filter, background-color. Las propiedades que saltan entre palabras clave, como display o font-family, cambian de golpe.

height: auto es la que más problemas da: un panel que se abre de height: 0 a height: auto no se anima por defecto, porque el navegador no calcula los valores entre 0 y "auto". Una alternativa fiable es un contenedor grid cuya única fila pasa de 0fr a 1fr:

aria-expanded les dice a los usuarios de lectores de pantalla si el panel está abierto, algo que la animación sola no hace.

Ejecutar código cuando termina una transición

El evento transitionend se dispara cuando termina una transición, una vez por propiedad. Úsalo para hacer algo después del movimiento, como mover el foco o quitar un elemento:

Respeta el movimiento reducido

Algunas personas activan "reducir movimiento" en la configuración de su sistema porque el movimiento en pantalla las marea o las distrae. Mantén los desvanecidos de color y opacidad y elimina los movimientos grandes con una media query:

@media (prefers-reduced-motion: reduce) {
  .btn { transition: background-color 0.2s ease; } /* no movement, only the color */
}

Mantén las transiciones fluidas

transform y opacity son las propiedades más baratas de animar: el navegador puede mover y desvanecer un elemento sin recalcular el layout. Hacer transiciones de width, height, top o margin obliga al navegador a volver a acomodar la página en cada fotograma, lo que puede ir a tirones en teléfonos lentos. Para mover algo, prefiere transform: translate() antes que left o margin. La página de transform explica las funciones.

Errores comunes

  • transition solo en la regla :hover. El efecto se anima al entrar, pero vuelve de golpe cuando termina el hover. Pon transition en la regla base.
  • Una duración sin unidad. transition: opacity 300 es inválido. Escribe 300ms o 0.3s.
  • transition: all. Anima todas las propiedades que cambian, incluidas las que no querías animar, y puede volver lentos los cambios de layout. Enumera las propiedades.
  • Esperar que display: none se desvanezca. display cambia de golpe. Desvanece opacity (y pon visibility: hidden cuando termine el desvanecido).
  • Hacer una transición a height: auto. Salta. Usa la técnica de grid-template-rows de arriba.
  • Duraciones largas en interacciones pequeñas. Cualquier cosa de más de unos 400ms en un botón o un menú se siente lenta.

Preguntas frecuentes

¿Cómo funcionan las transiciones CSS?

Declaras en un elemento qué propiedades deben animarse y durante cuánto tiempo, por ejemplo transition: background-color 0.3s ease;. Cuando cambia el valor de esa propiedad (con :hover, una clase o JavaScript), el navegador anima del valor anterior al nuevo en lugar de cambiarlo de golpe.

¿En qué orden van los valores de la abreviatura transition?

transition: property duration timing-function delay;, por ejemplo transition: opacity 0.3s ease-in 0.1s;. La única regla estricta es que el primer valor de tiempo es la duración y el segundo es el retraso. Separa varias transiciones con comas.

¿Por qué no funciona mi transición CSS?

Causas comunes: el transition solo está en la regla :hover (así que se anima al entrar y vuelve de golpe), la propiedad no se puede animar (display, o height hasta auto), la duración no tiene unidad (0.3 en lugar de 0.3s), o el valor cambia en el mismo momento en que el elemento se agrega a la página.

¿Se puede hacer una transición a height: auto?

No con una transición de height simple en todos los navegadores: interpolar hasta auto necesita la propiedad más nueva interpolate-size, que todavía no es compatible en todas partes. Las alternativas habituales son animar grid-template-rows de 0fr a 1fr en un contenedor grid, o animar max-height hasta un valor mayor que el contenido.

¿Qué diferencia hay entre transition y animation en CSS?

Una transición se ejecuta una vez, entre dos valores, cuando cambia una propiedad. Una animación usa @keyframes, puede tener muchos pasos, empieza sola cuando carga la página y puede repetirse o ejecutarse en bucle.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR