Una animación CSS en un ejemplo
Una animación tiene dos partes: @keyframes, que describe los pasos, y la propiedad animation, que los aplica a un elemento con una duración. Esta tarjeta entra deslizándose y apareciendo cuando carga la página:
Edita el código (o cambia la duración a 2s) y la vista previa se recarga, así que puedes ver entrar la tarjeta otra vez. El bloque @media (prefers-reduced-motion: reduce) reemplaza los keyframes por un simple desvanecido solo para los lectores cuyo sistema está configurado para reducir el movimiento.
Sintaxis de @keyframes
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.08); }
100% { transform: scale(1); }
}
fromes lo mismo que0%ytoes lo mismo que100%.- Agrega tantos pasos en porcentaje como necesites. Los pasos con los mismos estilos pueden compartir línea:
0%, 100% { ... }. - Una propiedad que falta en el primer o el último keyframe se anima desde o hasta el valor propio del elemento.
- El nombre (
pulse) es lo que le pasas aanimation-name. Distingue mayúsculas y minúsculas y no puede ser una palabra clave comonone.
Las propiedades de animation
| Propiedad | Qué define | Por defecto |
|---|---|---|
animation-name | qué @keyframes ejecutar | none |
animation-duration | la duración de un ciclo | 0s |
animation-timing-function | la curva de velocidad entre keyframes | ease |
animation-delay | espera antes del primer ciclo (negativo empieza a mitad de camino) | 0s |
animation-iteration-count | cantidad de ciclos, o infinite | 1 |
animation-direction | normal, reverse, alternate, alternate-reverse | normal |
animation-fill-mode | estilos antes y después: none, forwards, backwards, both | none |
animation-play-state | running o paused | running |
La abreviatura los acepta casi en cualquier orden. La única regla es que el primer valor de tiempo es la duración y el segundo el retraso:
.loader {
animation: pulse 1.2s ease-in-out 0.2s infinite alternate both;
/* name duration timing delay count direction fill */
}
direction y fill-mode, en vivo
Elige una dirección, un fill mode y una cantidad, y presiona Play. La caja se mueve 200px hasta el final de la pista. El indicador dice dónde quedó cuando terminó la animación:
Qué observar:
fill-mode: none(el valor por defecto): después del último fotograma la caja vuelve de golpe a x = 0 y se pone ámbar otra vez.forwards: se queda en el último keyframe. Connormaleso es x = 200 y verde; conreversetermina en x = 0 y azul, porque el último keyframe reproducido fuefrom.alternatecon una cantidad de 2 va y vuelve, así que incluso conforwardstermina en x = 0.
Bucles infinitos: un indicador de carga
infinite repite para siempre, y un animation-delay en cada hijo los desfasa para que se muevan por turnos. Mantén los bucles tranquilos: lentos, pequeños, sin destellos.
role="status" con un aria-label les dice a los usuarios de lectores de pantalla que algo está cargando, algo que los puntos solos no dicen. Para un círculo que gira, consulta la página de rotar.
Pausar y controlar animaciones
animation-play-state: paused congela una animación donde está, y running la continúa desde ahí. Pasa el mouse por la barra de abajo para pausarla:
Desde JavaScript, element.getAnimations() devuelve las animaciones CSS en curso, cada una con pause(), play(), cancel() y un currentTime que puedes leer o cambiar. El evento animationend se dispara cuando termina una animación no infinita, y animationiteration al final de cada ciclo.
Respeta el movimiento reducido y nunca uses destellos
Dos reglas de accesibilidad se aplican a toda animación:
- Movimiento reducido. Las personas pueden pedirle a su sistema menos movimiento porque el movimiento las hace sentir mal. El patrón más seguro es agregar movimiento solo cuando no han pedido menos:
@media (prefers-reduced-motion: no-preference) {
.hero-title { animation: slide-in 0.8s ease-out both; }
}
- Sin destellos. El contenido que destella más de tres veces por segundo puede provocar convulsiones. Evita por completo los parpadeos rápidos y de alto contraste.
Mantén las animaciones fluidas
Anima transform y opacity cuando puedas. El navegador puede aplicarlas sin volver a acomodar la página, así que se mantienen fluidas incluso en teléfonos lentos. Animar width, height, top, left o margin recalcula el layout en cada fotograma. Para mover un elemento, usa translate() de la página de transform.
Errores comunes
- Sin duración.
animation: fade;no hace nada, porque la duración por defecto es0s. - Un nombre que no coincide.
animation-namedebe coincidir exactamente con el nombre de@keyframes, mayúsculas incluidas. - Volver de golpe al final. Agrega
forwards(oboth) para conservar el último keyframe. - Un parpadeo antes de que empiece una animación con retraso. Durante
animation-delayel elemento muestra sus estilos normales.backwards(oboth) aplica el primer keyframe durante el retraso. - Reiniciar una animación poniendo el mismo valor. Volver a poner el mismo
animationno hace nada. Quítalo, fuerza un reflow (el.offsetWidth) y vuelve a ponerlo, como hace el botón Play de arriba. - Animar
display. Cambia de golpe. Animaopacityytransform.
Preguntas frecuentes
¿Cómo se hace una animación en CSS?
Define los pasos con @keyframes name { from { ... } to { ... } } y aplícala a un elemento con la propiedad animation y una duración: animation: name 1s ease-out;. La duración es obligatoria, porque su valor por defecto es 0s.
¿Qué hace animation-fill-mode: forwards?
Mantiene los estilos del último keyframe cuando termina la animación. Sin él, el elemento vuelve de golpe a sus estilos normales. backwards aplica el primer keyframe durante el retraso, y both hace las dos cosas.
¿Cómo hago que una animación CSS se repita para siempre?
Define animation-iteration-count: infinite, o agrega infinite a la abreviatura: animation: spin 1s linear infinite;. Agrega alternate para reproducirla hacia adelante y luego hacia atrás en cada ciclo.
¿Qué diferencia hay entre animation y transition en CSS?
Una transición anima una propiedad entre dos valores cuando cambia, normalmente en hover o con un cambio de clase. Una animación se ejecuta sola en cuanto se aplica, puede tener cualquier cantidad de keyframes y puede repetirse, invertirse y pausarse.
¿Cómo pauso una animación CSS?
Define animation-play-state: paused en el elemento, por ejemplo en :hover o con una clase que agrega JavaScript. Volver a ponerlo en running la continúa desde donde se detuvo.
¿Cómo desactivo las animaciones para quienes prefieren menos movimiento?
Envuelve la animación en @media (prefers-reduced-motion: no-preference) { ... }, o quítala dentro de @media (prefers-reduced-motion: reduce) { ... }. La consulta sigue la opción de reducir movimiento del sistema operativo del usuario.