Hover me
Generated CSS

Transiciones CSS — Guía de Referencia Completa

Una transición CSS es una de las herramientas más poderosas en el kit de un desarrollador front-end. Cuando el valor de una propiedad CSS cambia — porque el usuario pasó el cursor sobre un elemento, se alternó una clase mediante JavaScript, o un campo recibió el foco — el navegador normalmente aplica ese cambio de forma instantánea. Una transición intercepta ese cambio y anima desde el valor anterior al nuevo durante una duración definida, produciendo una retroalimentación de interfaz suave y profesional sin una sola línea de JavaScript de animación.

El modelo mental es sencillo: declaras en un elemento qué propiedades deben animarse, cuánto tiempo deben tomar, qué curva de aceleración deben seguir y si debe haber un retraso antes de que comiencen. El navegador maneja toda la interpolación fotograma a fotograma automáticamente, usando la GPU para propiedades compuestas como transform y opacity — por eso esas dos son el estándar de oro para la animación de alto rendimiento.

Cómo funciona la propiedad transition

La propiedad abreviada transition combina cuatro subpropiedades en una sola declaración. Puedes apuntar a múltiples propiedades separándolas con comas, y cada valor separado por coma puede tener su propia duración, aceleración y retraso. Esto es mucho mejor que usar transition: all, que obliga al navegador a verificar cada propiedad CSS en cada fotograma — una trampa de rendimiento que causa trabajo de repintado innecesario incluso para propiedades que nunca cambias.

Las cuatro subpropiedades son transition-property (qué valor CSS animar), transition-duration (cuánto tiempo), transition-timing-function (la curva de aceleración) y transition-delay (cuánto tiempo esperar antes de comenzar). El retraso es especialmente útil para efectos escalonados — puedes hacer que una lista de elementos aparezca uno tras otro dando a cada uno un retraso progresivamente mayor, usando la misma clase CSS base.

La función de tiempo es la personalidad

Si la duración determina cuánto tiempo tarda una animación, la función de tiempo determina cómo se siente. Dos animaciones con la misma duración pero diferentes funciones de tiempo se sienten completamente distintas. ease-out — que comienza rápido y se desacelera — imita el comportamiento físico de un objeto que llega y se asienta, por eso se siente natural para elementos que entran a la pantalla. ease-in — que comienza lento y acelera — refleja un objeto ganando impulso antes de salir, siendo correcto para salidas. ease-in-out es simétrico y funciona bien para transiciones entre dos estados iguales como expandir un panel. linear se siente mecánico y robótico, lo cual es exactamente lo que quieres para cosas como barras de progreso.

Los atajos de palabras clave son simplemente alias convenientes para valores de cubic-bezier(). El verdadero poder viene cuando defines tu propia curva — un resorte con sobreimpulso usando un valor Y superior a 1.0, o un efecto de anticipación usando un valor Y negativo.

¿Qué propiedades se pueden transicionar realmente?

No todas las propiedades CSS admiten interpolación. Una propiedad debe tener valores entre los que el navegador pueda calcular pasos intermedios. Los valores numéricos, colores, longitudes y porcentajes son todos interpolables. Los valores discretos como display, visibility (parcialmente) y font-family no lo son.

El rendimiento importa tanto como el soporte. El canal de renderizado del navegador tiene tres etapas: layout, paint y composite. Desencadenar un reflujo de layout en cada fotograma — lo que ocurre al transicionar width, height, top o left — es costoso y causa tartamudeo. Solo transform y opacity son manejadas completamente por la capa de composición GPU, lo que significa que se animan a la tasa de fotogramas completa sin impacto en el layout o el pintado.

El truco de visibility para ocultar elementos

Uno de los desafíos más comunes de transición es hacer que un elemento desaparezca suavemente. Configurar display: none lo elimina del documento instantáneamente — no puedes transicionar hacia o desde él. La solución es combinar opacity con visibility. La propiedad visibility acepta un retraso de transición, por lo que puedes mantener el elemento visualmente opaco hasta que la desvanecida de opacidad esté completa, luego hacerlo no interactivo.

Escalonamiento con transition-delay

El escalonamiento — hacer que múltiples elementos se animen secuencialmente en lugar de todos a la vez — crea una sensación más dinámica y viva en una UI. La técnica es simple: aplica la misma transición base a un conjunto de elementos, luego dale a cada elemento un transition-delay progresivamente más largo usando selectores :nth-child. Cuando se alterna la clase del padre, los hijos se animan uno tras otro.

Retraso negativo — comenzar a mitad de animación

Un valor de transition-delay negativo le dice al navegador que comience la transición como si ya hubiera estado ejecutándose durante esa duración. Un valor de -300ms significa que la animación comienza en la marca de los 300ms en lugar de en 0. Esto es útil para estados de carga donde quieres que un elemento aparezca ya en movimiento.

La técnica FLIP

FLIP (First, Last, Invert, Play) es un patrón para animar cambios de layout que de otro modo requerirían transicionar propiedades costosas. Registras la posición del elemento antes del cambio (First), aplicas el cambio (Last), calculas la diferencia y aplicas el inverso como transform (Invert), luego eliminas el inverso para que el navegador anime a la posición final (Play). El resultado es una animación suave compuesta por GPU incluso aunque el layout subyacente haya cambiado.

Rendimiento y will-change

La propiedad will-change es una sugerencia al navegador de que un elemento está a punto de animarse, dándole la oportunidad de promover ese elemento a su propia capa de composición GPU antes de que comience la animación. La propiedad debe usarse con moderación — cada capa promovida consume memoria GPU, y promover todo anula el propósito. Aplícala solo a elementos que se animan frecuentemente.

Accesibilidad y prefers-reduced-motion

Los usuarios con trastornos vestibulares, migrañas o sensibilidad al movimiento pueden experimentar malestar físico genuino por las animaciones en pantalla. Los sistemas operativos exponen una configuración de accesibilidad "Reducir movimiento", consultable mediante la media query prefers-reduced-motion. El criterio de éxito 2.3.3 de WCAG 2.1 requiere que el movimiento activado por la interacción pueda desactivarse.

Transiciones vs animaciones CSS

Las transiciones y las animaciones CSS resuelven problemas diferentes. Las transiciones siempre son activadas por un cambio de estado y animan entre exactamente dos estados — el valor inicial y el final. Se invierten automáticamente cuando el cambio de estado se invierte. No requieren declaración de @keyframes. Las animaciones CSS, por el contrario, pueden repetirse en bucle, pueden definir múltiples fotogramas clave intermedios y pueden ejecutarse automáticamente al cargar la página.

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

Las cuatro causas más comunes: (1) La declaración transition está en el estado hover/activo en lugar del elemento base — el elemento base debe declarar la transición para que se invierta suavemente. (2) La propiedad no es interpolable — display, z-index en elementos no posicionados y los valores de degradado background-image no pueden transicionarse. (3) Ambos estados tienen valores calculados idénticos. (4) transition-duration falta o tiene por defecto 0s.

¿Cuál es la diferencia entre transition-delay y animation-delay?

Ambos retrasan el inicio de la animación, pero transition-delay retrasa el inicio desde el desencadenante (p. ej., desde el hover hasta que comienza la animación), mientras que animation-delay retrasa el inicio de la animación de fotogramas clave desde que el elemento se carga o se aplica la clase. Los valores negativos funcionan en ambos.

¿Se pueden transicionar los degradados background-image?

No — los valores de degradado CSS son técnicamente valores background-image, y los valores de imagen no son interpolables. El navegador no puede calcular un punto intermedio entre dos declaraciones de degradado. La solución alternativa: apila un pseudo-elemento con el nuevo degradado detrás o encima del fondo actual, y transiciona su opacidad de 0 a 1.

¿Cómo hago que un elemento transite desde display:none a visible?

No puedes — los cambios de display son instantáneos. Usa el patrón de opacidad y visibilidad: establece opacity: 0; visibility: hidden y transiciona ambos, con un retraso coincidente en la visibilidad para la dirección de ocultación. Para el colapso basado en altura, usa max-height: 0 transicionando a un max-height mayor que el contenido.

¿Qué duración debo usar?

Las pautas de Material Design 3 de Google recomiendan 100–200ms para cambios de estado de componentes pequeños, 250–400ms para transiciones medianas y 400–600ms para transiciones de pantalla completa. Cualquier cosa bajo 100ms es imperceptible. Cualquier cosa sobre 500ms empieza a sentirse lenta para interacciones repetidas.

¿Debo usar transiciones o bibliotecas de animación JavaScript?

Las transiciones CSS son ideales para cambios de estado discretos impulsados por cambios de clase o atributo — efectos de hover, anillos de enfoque, alternancias, deslizamientos de cajón, aperturas de modal. Las bibliotecas de animación JavaScript como GSAP o Motion One son mejores cuando necesitas secuenciación entre múltiples elementos, simulaciones físicas o animaciones vinculadas al scroll.

Tool last updated: