Animaciones CSS
Las transiciones enseñaron A → B con un disparador. Transform enseñó adónde va la caja pintada. Las animaciones escriben una línea de tiempo: pulsar un punto de estado, girar un loader sin fin, entrar las tarjetas en cascada — con @keyframes para los pasos y animation para ejecutarlos.
Qué es una animación
Dos piezas: un conjunto de keyframes con nombre (@keyframes) que lista estilos en porcentajes (o from / to), y una regla que reproduce ese nombre con duración, delay opcional, número de iteraciones, dirección, función de tiempo y fill-mode. El navegador interpola entre las paradas del keyframe.
La coincidencia de nombres es estricta: animation-name: pulse solo corre si existe @keyframes pulse. Renombre uno sin el otro y nada se moverá.
Controles de un vistazo
📊 Piezas centrales de la animación
| Pieza | Función |
|---|---|
@keyframes name { … } |
Línea de tiempo de valores de propiedad en % / from / to |
animation-name |
Qué conjunto de keyframes reproducir |
animation-duration |
Cuánto dura un ciclo (s o ms) |
animation-timing-function |
Suavizado dentro del ciclo (ease, linear, …) |
animation-delay |
Espera antes del primer ciclo |
animation-iteration-count |
Cuántos ciclos (number o infinite) |
animation-direction |
normal, reverse, alternate, alternate-reverse |
animation-fill-mode |
Estilos antes/después (none, forwards, backwards, both) |
animation shorthand |
name → duration → timing → delay → iteration → direction → fill-mode (orden habitual) |
Rara vez necesita todos los longhands a la vez. Empiece con nombre + duración; añada infinite para loaders, alternate para ida y vuelta, y forwards cuando el último keyframe deba quedarse.
Primera línea de tiempo — pulso calmado
Opacity y transform son amigables con la pintura. Un pulso suave es un clásico primer ejercicio con @keyframes.
@keyframes pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.55;
transform: scale(0.92);
}
}
.status-dot {
display: inline-block;
width: 0.75rem;
height: 0.75rem;
border-radius: 50%;
background: #16a34a;
animation: pulse 1.4s ease-in-out infinite;
}
0% y 100% coinciden para que el bucle cierre limpio. infinite mantiene el ciclo — bien para un indicador pequeño; ruidoso si anima un hero entero.
Giro infinito — a los loaders les gusta linear
Rotación con linear e infinite se lee como spinner continuo. Combínelo con un fallback de reduced motion que oculte o congele el giro.
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.loader {
width: 2rem;
height: 2rem;
border: 3px solid #e5e7eb;
border-top-color: #2563eb;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.loader {
animation: none;
border-top-color: #e5e7eb;
}
}
to es atajo de 100%. Empezar en el 0% por defecto (sin transform) basta cuando solo importa el final del giro.
Delay y stagger — mismos keyframes, distintos inicios
Un conjunto de keyframes puede mover muchos elementos. Escalone con animation-delay para que una lista se sienta secuencial sin escribir tres animaciones distintas.
@keyframes fade-up {
from {
opacity: 0;
transform: translateY(0.75rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.reveal-list li {
opacity: 0;
animation: fade-up 0.45s ease forwards;
}
.reveal-list li:nth-child(1) { animation-delay: 0s; }
.reveal-list li:nth-child(2) { animation-delay: 0.08s; }
.reveal-list li:nth-child(3) { animation-delay: 0.16s; }
forwards conserva los estilos del keyframe final tras el ciclo — sin ello, los ítems pueden volver a opacity: 0 de la regla base. Ahí animation-fill-mode hace trabajo real.
fill-mode en una entrada única
Las entradas suelen ejecutarse una vez. fill-mode decide si los estilos aplican antes del delay y después del último fotograma.
@keyframes card-in {
from {
opacity: 0;
transform: translateY(1rem) scale(0.98);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
.card-enter {
animation: card-in 0.5s ease 0.1s both;
}
Shorthand aquí: nombre card-in, duración 0.5s, easing ease, delay 0.1s, fill-mode both. both aplica el primer keyframe durante el delay y mantiene el último después.
Dirección, play state y cuándo no animar
animation-direction: alternate hace ciclos impares hacia adelante y pares hacia atrás — útil para un rebote suave sin duplicar keyframes. animation-play-state: paused congela una animación en curso (p. ej. pausa al hover en bucles decorativos).
Para un cambio de color al hover simple, siga con transitions. Use animaciones cuando necesite bucles, historias de varios pasos o movimiento no atado a un solo toggle de estado. Prefiera transform y opacity dentro de keyframes; animar width, height o top pesa más y a menudo sacude el layout.
Pruébelo usted
- Construya un pulso con tres paradas (
0%/50%/100%) solo en opacity; luego añada unscalepequeño. - Haga un spinner con
spin+linear+infinite; cambie aeasey note la sensación desigual. - Escalone tres badges con los mismos keyframes
fade-upy delays0s,0.1s,0.2s— compare con y sinforwards. - Use shorthand
animation: card-in 0.5s ease 0.15s bothen un panel; quitebothy observe el snap-back. - Bajo
prefers-reduced-motion: reduce, pongaanimation: none(o un fade corto) en bucles decorativos.
Errores comunes
- Esperar que un fade hover A→B «haga loop» — eso es territorio de animación, no una transition solitaria
- Desajuste tipográfico entre
animation-namey el nombre de@keyframes— silencio total infiniteen zonas grandes y llamativas sin plan de pausa o reduced motion- Animar propiedades de layout (
width,margin,top) cuando bastaría transform/opacity - Omitir
forwards/bothen reveals de una sola vez que parten deopacity: 0en la regla base
Resumen
@keyframesdefinen la línea de tiempo;animation(o longhands) la reproducen- Use iteración, dirección, delay y fill-mode para bucles, rebote, stagger y finales que se quedan
- Prefiera transform/opacity; respete prefers-reduced-motion en movimiento decorativo
- Transitions para cambios de estado simples; animaciones para movimiento multietapa y repetido
- Siguiente en Effects & Motion: CSS Filters
🧠 Pon a Prueba tu Conocimiento
Pon a Prueba tu Conocimiento
Ponte a prueba con este cuestionario interactivo y descubre qué tan bien entiendes el tema
📝 Instrucciones
- Lee cada pregunta cuidadosamente
- Selecciona la mejor respuesta para cada pregunta
- Puedes repetir el quiz tantas veces como quieras
- Tu progreso se mostrará en la parte superior