Generador CSS

Generador de animaciones CSS

Elige un efecto, ajusta el tiempo y dibuja la curva de aceleración. Te llevas el bloque @keyframes y la propiedad animation listos para pegar, con el respeto por quien pide menos movimiento ya incluido.

Vista previa

Lienzo

Vista previa en reproducción. Pulsa «Reiniciar» para verla otra vez desde el principio.

CSS generado


              

¿Buscas otro efecto? Toda la colección está en código web, y el generador de degradados te prepara el fondo sobre el que se va a mover esto.

Keyframes y animation: dos piezas que se necesitan

Una animación CSS son siempre dos cosas separadas. El bloque @keyframes describe qué pasa: los fotogramas clave, del 0% al 100% (o from y to cuando solo hay dos). La propiedad animation describe cuándo y cómo: a qué elemento se aplica, cuánto dura, con qué curva, cuántas veces se repite y qué deja al terminar.

El bloque de keyframes vive fuera de cualquier selector y se puede reutilizar en veinte sitios distintos con tiempos diferentes. Por eso conviene ponerle un nombre que describa el movimiento (deslizar, latido) y no el elemento (animacion-header): el mismo desplazamiento te servirá luego en una tarjeta y en un aviso. En la propiedad, el orden abreviado es nombre, duración, curva, retardo, repeticiones, dirección y relleno. Si pones dos tiempos, el primero siempre es la duración y el segundo el retardo.

fill-mode: el valor que más se malinterpreta

Fuera del tiempo que dura la animación, el elemento vuelve a ser lo que dice su CSS normal. animation-fill-mode es lo único que cambia eso, y de ahí vienen la mitad de los efectos raros:

none no conserva nada: si tu último fotograma es opacity: 1 pero el elemento tiene opacity: 0 en su CSS, al acabar desaparece de golpe. forwards lo congela en el último fotograma, que es lo que quieres en una entrada. backwards le aplica el primer fotograma durante el retardo, y evita el clásico parpadeo de un elemento que se ve un instante antes de empezar a animarse. both hace las dos cosas y es la respuesta correcta casi siempre. Si una animación de entrada te parpadea al principio o salta al final, el culpable es este valor, no tus keyframes.

Curvas de aceleración, y por qué linear casi nunca se ve bien

La curva reparte el progreso a lo largo del tiempo. Con linear el elemento avanza siempre a la misma velocidad: arranca de golpe a máxima velocidad y se detiene en seco. Nada en el mundo físico se mueve así, y el ojo lo nota aunque no sepa explicar por qué. Su único terreno legítimo es el movimiento continuo que no tiene principio ni final visibles: una rueda que gira, un indicador de carga.

Para todo lo demás, la regla práctica es sencilla. Lo que entra en pantalla usa una curva que frena al final (ease-out): llega rápido y se posa. Lo que sale usa una que acelera (ease-in): se va sin hacerse esperar. Lo que se mueve de un punto a otro dentro de la pantalla usa ease-in-out. Y cuando necesitas carácter, cubic-bezier() te deja pasarte del 100 % —un valor de Y mayor que 1— para conseguir ese rebotito de sobrepaso que hace que un botón parezca vivo. En el panel de la derecha lo ves dibujado antes de escribir una sola línea.

Anima transform y opacity, y poco más

El navegador pinta una página en fases: calcula el diseño, dibuja los píxeles y compone las capas. Animar width, height, top, left, margin o padding obliga a rehacer el diseño entero en cada fotograma, y en un móvil eso se traduce en tirones. transform y opacity se resuelven en la última fase, en la tarjeta gráfica, sin tocar el diseño.

La traducción es directa: en vez de left usa transform: translateX(); en vez de width, scale(); en vez de aparecer cambiando display, cambia opacity. Es la misma técnica que mueve el texto ondulado de este sitio sin que el navegador sude.

prefers-reduced-motion no es un detalle

Hay gente para la que el movimiento en pantalla no es decorativo: provoca mareo, náuseas o migraña. Los sistemas operativos tienen desde hace años una casilla para pedir menos movimiento, y el navegador la expone en @media (prefers-reduced-motion: reduce). Ignorarla no es quedarse corto en accesibilidad: es hacerle daño a alguien.

Por eso el código que sale de esta herramienta trae siempre ese bloque, y por eso la vista previa de arriba arranca en pausa si tu sistema pide menos movimiento. Respetarlo no significa quitar toda vida a la interfaz: un animation: none basta en la mayoría de casos, y cuando el movimiento comunica algo (un elemento que aparece), puedes dejar solo el opacity y quitar el desplazamiento. Lo que no vale es no escribir el bloque. Si empiezas a construir tu sistema de estilos, esto va junto a los tokens de color y tipografía desde el primer día, igual que las paletas que preparas en colores en vivo.

Preguntas frecuentes

¿Cuál es la diferencia entre una transición y una animación en CSS?

Una transición necesita que algo cambie para dispararse —un hover, una clase que añades con JavaScript— y solo va del estado A al estado B. Una animación con keyframes se reproduce sola en cuanto el elemento existe, admite todos los pasos intermedios que quieras y controla repeticiones, dirección y retardo. Si el efecto es una respuesta a la acción del usuario, usa transición; si es un movimiento propio del elemento, usa animación.

¿Qué hace exactamente animation-fill-mode?

Decide qué estilos conserva el elemento fuera del tiempo que dura la animación. Con none vuelve a su aspecto normal antes de empezar y al terminar. Con forwards se queda congelado en el último fotograma. Con backwards adopta el primer fotograma durante el retardo, antes de arrancar. Con both hace las dos cosas, y es lo que quieres casi siempre en animaciones de entrada para que el elemento no parpadee ni salte al final.

¿Por qué mi animación se ve a tirones?

Casi siempre porque estás animando propiedades que obligan al navegador a recalcular el diseño de la página en cada fotograma, como width, height, top, left, margin o padding. Cambia esos movimientos por transform (translate, scale, rotate) y usa opacity para las apariciones: el navegador los resuelve en la tarjeta gráfica sin rehacer el diseño, y la animación pasa a ir fluida.

¿Cómo hago que la animación se reproduzca cuando el elemento entra en pantalla?

Pon la animación en una clase, por ejemplo .animado, y añádesela al elemento con un IntersectionObserver cuando entre en el viewport. Con animation-fill-mode: both el elemento queda en su sitio al terminar. También puedes hacerlo sin JavaScript con animation-timeline: view(), aunque su soporte todavía no es universal.