CSS

CSS

Tutorial CSS: Animaciones

Aprende a crear y controlar animaciones CSS con @keyframes, duración, iteración y estados para interfaces dinámicas y profesionales.

Aprende CSS y certifícate

Definición de keyframes con @keyframes

Las animaciones en CSS nos permiten crear movimientos y cambios visuales en los elementos HTML sin necesidad de JavaScript. El corazón de cualquier animación en CSS es la regla @keyframes, que define los estados por los que pasará un elemento durante la animación.

La regla @keyframes funciona como un guion para nuestra animación, especificando exactamente qué propiedades CSS cambiarán y en qué momento. Imagina que estás creando una película fotograma a fotograma: cada keyframe representa un punto específico en la línea de tiempo de la animación.

Sintaxis básica

La estructura de @keyframes es sencilla pero potente:

@keyframes nombreDeLaAnimacion {
  /* Definición de los estados */
}

Donde nombreDeLaAnimacion es un identificador único que utilizaremos más adelante para aplicar esta animación a elementos HTML específicos.

Definiendo estados con porcentajes

Dentro de la regla @keyframes, definimos los estados de la animación utilizando porcentajes. Estos porcentajes representan el progreso de la animación desde el inicio (0%) hasta el final (100%):

@keyframes cambioColor {
  0% {
    background-color: red;
  }
  50% {
    background-color: blue;
  }
  100% {
    background-color: green;
  }
}

En este ejemplo, creamos una animación llamada cambioColor que:

  • Comienza con un fondo rojo
  • A mitad de la animación (50%) cambia a azul
  • Termina con un fondo verde

Usando from y to

Para animaciones simples que solo tienen un estado inicial y final, podemos usar las palabras clave from y to como alternativa a 0% y 100%:

@keyframes moverDerecha {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(200px);
  }
}

Esta animación mueve un elemento 200 píxeles hacia la derecha de manera fluida.

Múltiples propiedades en cada keyframe

Podemos animar varias propiedades simultáneamente en cada keyframe:

@keyframes animacionCompleta {
  0% {
    background-color: yellow;
    transform: scale(1);
    opacity: 1;
  }
  50% {
    background-color: orange;
    transform: scale(1.5);
  }
  100% {
    background-color: red;
    transform: scale(1);
    opacity: 0.5;
  }
}

En este ejemplo, estamos animando el color de fondo, el tamaño y la opacidad del elemento simultáneamente.

Keyframes intermedios

No estamos limitados a usar solo el inicio y el final. Podemos definir tantos estados intermedios como necesitemos:

@keyframes arcoiris {
  0% { background-color: red; }
  14% { background-color: orange; }
  28% { background-color: yellow; }
  42% { background-color: green; }
  56% { background-color: blue; }
  70% { background-color: indigo; }
  84% { background-color: violet; }
  100% { background-color: red; }
}

Esta animación crea un efecto de arcoíris cíclico, pasando por todos los colores y volviendo al inicio.

Ejemplo práctico: Animación de pulso

Veamos un ejemplo práctico de una animación de pulso que podría usarse para destacar un botón o elemento importante:

@keyframes pulso {
  0% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(0, 123, 255, 0.7);
  }
  
  70% {
    transform: scale(1.05);
    box-shadow: 0 0 0 10px rgba(0, 123, 255, 0);
  }
  
  100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(0, 123, 255, 0);
  }
}

Esta animación crea un efecto de pulso donde el elemento:

  1. Comienza en su tamaño normal
  2. Se expande ligeramente (5%) mientras emite un resplandor
  3. Vuelve a su tamaño original mientras el resplandor se desvanece

Omitiendo porcentajes

CSS es lo suficientemente inteligente para interpolar entre estados, por lo que no necesitamos definir cada porcentaje posible:

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

En este ejemplo, CSS calculará automáticamente todos los valores intermedios de opacidad entre 0 y 1.

Animaciones no lineales con múltiples keyframes

Podemos crear efectos más complejos definiendo varios keyframes:

@keyframes rebote {
  0%, 20%, 50%, 80%, 100% {
    transform: translateY(0);
  }
  40% {
    transform: translateY(-30px);
  }
  60% {
    transform: translateY(-15px);
  }
}

Esta animación crea un efecto de rebote donde el elemento:

  • Permanece en su posición original en los puntos 0%, 20%, 50%, 80% y 100%
  • Salta hacia arriba 30px en el punto 40%
  • Salta hacia arriba 15px en el punto 60%

Consideraciones importantes

Al trabajar con @keyframes, ten en cuenta estos puntos:

  • Los nombres de las animaciones distinguen entre mayúsculas y minúsculas.
  • Puedes reutilizar la misma animación en múltiples elementos.
  • Las propiedades que no se especifican en un keyframe se interpolan automáticamente.
  • Si defines el mismo porcentaje varias veces, se utilizará la última definición.
@keyframes ejemplo {
  0% {
    background-color: red;
    transform: translateX(0);
  }
  /* Si no especificamos el background-color en 100%,
     CSS interpolará automáticamente desde rojo */
  100% {
    transform: translateX(100px);
  }
}

En este ejemplo, el color de fondo cambiará gradualmente desde rojo hasta el color original del elemento.

Con la regla @keyframes definida, el siguiente paso será aplicar esta animación a elementos HTML específicos mediante las propiedades animation-name, animation-duration y otras propiedades de control que veremos en las siguientes secciones.

Control de animación con animation-name y animation-duration

Una vez que hemos definido nuestras animaciones con @keyframes, necesitamos aplicarlas a los elementos HTML. Para ello, CSS nos proporciona varias propiedades que nos permiten controlar cómo se ejecutan estas animaciones. Las dos propiedades fundamentales para comenzar son animation-name y animation-duration.

La propiedad animation-name

La propiedad animation-name es la encargada de vincular un elemento con la animación que hemos creado previamente mediante @keyframes. Su sintaxis es muy sencilla:

.elemento {
  animation-name: nombreDeLaAnimacion;
}

Donde nombreDeLaAnimacion debe coincidir exactamente con el nombre que definimos en nuestra regla @keyframes.

Por ejemplo, si queremos aplicar la animación "fadeIn" a un botón:

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.button {
  animation-name: fadeIn;
}

Sin embargo, si solo especificamos el nombre de la animación, no veremos ningún efecto visible. Esto se debe a que necesitamos indicar cuánto tiempo durará la animación, y aquí es donde entra en juego la segunda propiedad esencial.

La propiedad animation-duration

La propiedad animation-duration establece la duración total de un ciclo completo de la animación. Se expresa en segundos (s) o milisegundos (ms):

.elemento {
  animation-name: nombreDeLaAnimacion;
  animation-duration: 2s; /* La animación durará 2 segundos */
}

Sin esta propiedad, la animación se ejecutaría instantáneamente (con duración 0), lo que la haría imperceptible para el usuario.

Combinando ambas propiedades

Para que una animación funcione correctamente, necesitamos como mínimo estas dos propiedades trabajando juntas:

.card {
  animation-name: slideIn;
  animation-duration: 1.5s;
}

Este código aplicará la animación "slideIn" al elemento con clase "card", y la animación durará 1.5 segundos.

Ejemplos prácticos

Veamos algunos ejemplos prácticos para entender mejor cómo funcionan estas propiedades:

Ejemplo 1: Animación de entrada suave

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.welcome-message {
  animation-name: fadeInUp;
  animation-duration: 0.8s;
}

Este ejemplo crea un efecto donde el mensaje aparece gradualmente mientras se desplaza hacia arriba, todo en 0.8 segundos.

Ejemplo 2: Animación de carga (spinner)

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.loader {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #3498db;
  border-radius: 50%;
  animation-name: spin;
  animation-duration: 2s;
}

Este código crea un indicador de carga circular que gira completamente en 2 segundos.

Valores de duración

La propiedad animation-duration acepta valores en:

  • Segundos: 2s (dos segundos)
  • Milisegundos: 500ms (medio segundo)
.quick-animation {
  animation-name: flash;
  animation-duration: 200ms; /* Animación rápida de 0.2 segundos */
}

.slow-animation {
  animation-name: fadeOut;
  animation-duration: 3s; /* Animación lenta de 3 segundos */
}

Consideraciones sobre la duración

La duración de una animación afecta significativamente a la experiencia del usuario:

  • Animaciones muy cortas (menos de 200ms) pueden pasar desapercibidas.
  • Animaciones muy largas (más de 5s) pueden resultar tediosas y afectar negativamente la experiencia.
  • Para efectos de interfaz (como hover, feedback de botones), se recomiendan duraciones entre 200-500ms.
  • Para transiciones de página o animaciones narrativas, duraciones entre 800ms-2s suelen funcionar bien.

Animaciones sin duración o sin nombre

Si omitimos alguna de estas propiedades, la animación no funcionará correctamente:

/* Sin animation-duration, la animación ocurre instantáneamente */
.element1 {
  animation-name: bounce;
  /* Sin duration, no se verá la animación */
}

/* Sin animation-name, no hay animación que aplicar */
.element2 {
  animation-duration: 2s;
  /* Sin name, la duración no tiene efecto */
}

Aplicando múltiples animaciones

Podemos aplicar varias animaciones al mismo elemento separando los valores con comas:

.notification {
  animation-name: fadeIn, shake;
  animation-duration: 1s, 0.5s;
}

En este ejemplo, la animación "fadeIn" durará 1 segundo, mientras que "shake" durará 0.5 segundos. Ambas animaciones se ejecutarán simultáneamente.

Ejemplo completo: Botón con efecto de pulso

Veamos un ejemplo completo de un botón con efecto de pulso:

@keyframes pulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.05);
  }
  100% {
    transform: scale(1);
  }
}

.cta-button {
  padding: 12px 24px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  
  /* Aplicamos la animación */
  animation-name: pulse;
  animation-duration: 2s;
}

Este código crea un botón que pulsa suavemente, expandiéndose y contrayéndose durante un ciclo de 2 segundos.

Compatibilidad con navegadores

Aunque las propiedades de animación tienen buen soporte en navegadores modernos, en proyectos que requieran compatibilidad con navegadores más antiguos, es recomendable usar prefijos de proveedor:

.element {
  -webkit-animation-name: slide;
  -webkit-animation-duration: 1s;
  -moz-animation-name: slide;
  -moz-animation-duration: 1s;
  animation-name: slide;
  animation-duration: 1s;
}

Sin embargo, en proyectos nuevos, los prefijos generalmente ya no son necesarios para las propiedades básicas de animación.

Con animation-name y animation-duration hemos establecido los fundamentos para controlar nuestras animaciones, pero CSS ofrece muchas más propiedades para personalizar el comportamiento de las animaciones, como veremos en las siguientes secciones.

Iteración y dirección con animation-iteration-count y animation-direction

Una vez que hemos definido nuestras animaciones con @keyframes y establecido sus nombres y duraciones, podemos controlar aspectos más avanzados como cuántas veces se ejecutará la animación y en qué dirección. Para esto, CSS nos proporciona las propiedades animation-iteration-count y animation-direction.

Control de repeticiones con animation-iteration-count

La propiedad animation-iteration-count determina cuántas veces se reproducirá la animación antes de detenerse. Podemos especificar un número concreto o hacer que la animación se repita indefinidamente.

.elemento {
  animation-name: bounce;
  animation-duration: 2s;
  animation-iteration-count: 3; /* La animación se ejecutará 3 veces */
}

Valores posibles:

  • Número entero positivo: La animación se ejecutará ese número exacto de veces.
  • Número decimal: La animación se ejecutará el número entero de veces y luego se detendrá en el punto proporcional al decimal.
  • infinite: La animación se repetirá indefinidamente.
.notification-bell {
  animation-name: ring;
  animation-duration: 0.5s;
  animation-iteration-count: 2; /* Sonará dos veces */
}

.loading-spinner {
  animation-name: spin;
  animation-duration: 1s;
  animation-iteration-count: infinite; /* Girará continuamente */
}

.partial-effect {
  animation-name: fade;
  animation-duration: 3s;
  animation-iteration-count: 1.5; /* Se ejecutará una vez completa y luego hasta la mitad */
}

El valor decimal es particularmente útil para efectos precisos. Por ejemplo, con animation-iteration-count: 2.5, la animación se ejecutará dos veces completas y luego hasta la mitad de la tercera repetición.

Controlando la dirección con animation-direction

La propiedad animation-direction define cómo debe reproducirse la secuencia de fotogramas: hacia adelante, hacia atrás o alternando entre ambas direcciones.

.elemento {
  animation-name: slide;
  animation-duration: 1s;
  animation-iteration-count: 3;
  animation-direction: alternate; /* Alterna entre adelante y atrás */
}

Valores posibles:

  • normal: La animación se reproduce hacia adelante en cada ciclo (valor predeterminado).
  • reverse: La animación se reproduce hacia atrás en cada ciclo.
  • alternate: La animación se reproduce hacia adelante en los ciclos impares y hacia atrás en los pares.
  • alternate-reverse: La animación se reproduce hacia atrás en los ciclos impares y hacia adelante en los pares.
.normal-animation {
  animation-name: move;
  animation-duration: 2s;
  animation-iteration-count: 3;
  animation-direction: normal; /* → → → */
}

.reverse-animation {
  animation-name: move;
  animation-duration: 2s;
  animation-iteration-count: 3;
  animation-direction: reverse; /* ← ← ← */
}

.alternate-animation {
  animation-name: move;
  animation-duration: 2s;
  animation-iteration-count: 3;
  animation-direction: alternate; /* → ← → */
}

.alternate-reverse-animation {
  animation-name: move;
  animation-duration: 2s;
  animation-iteration-count: 3;
  animation-direction: alternate-reverse; /* ← → ← */
}

Combinando iteración y dirección

La combinación de animation-iteration-count y animation-direction permite crear efectos más complejos y naturales:

@keyframes pendulum {
  0% { transform: rotate(0deg); }
  50% { transform: rotate(20deg); }
  100% { transform: rotate(0deg); }
}

.clock-pendulum {
  animation-name: pendulum;
  animation-duration: 1s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

En este ejemplo, creamos un efecto de péndulo que oscila suavemente de un lado a otro indefinidamente, alternando la dirección en cada ciclo para un movimiento más natural.

Ejemplos prácticos

Ejemplo 1: Indicador de carga pulsante

@keyframes pulse {
  0% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.2); opacity: 0.7; }
  100% { transform: scale(1); opacity: 1; }
}

.loading-indicator {
  width: 20px;
  height: 20px;
  background-color: #3498db;
  border-radius: 50%;
  animation-name: pulse;
  animation-duration: 1.5s;
  animation-iteration-count: infinite;
  animation-direction: normal;
}

Este código crea un círculo que pulsa continuamente, aumentando y disminuyendo su tamaño y opacidad.

Ejemplo 2: Banner con efecto de deslizamiento

@keyframes slide {
  0% { transform: translateX(0); }
  100% { transform: translateX(-100%); }
}

.banner-text {
  white-space: nowrap;
  animation-name: slide;
  animation-duration: 10s;
  animation-iteration-count: infinite;
  animation-direction: normal;
}

Este ejemplo crea un banner de texto que se desplaza continuamente de derecha a izquierda.

Ejemplo 3: Botón con efecto de rebote

@keyframes bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-10px); }
}

.bounce-button:hover {
  animation-name: bounce;
  animation-duration: 0.6s;
  animation-iteration-count: 3;
  animation-direction: alternate;
}

Este código aplica un efecto de rebote a un botón cuando el usuario pasa el cursor sobre él. El botón rebotará tres veces, alternando la dirección para un efecto más suave.

Casos de uso específicos

Animaciones de una sola vez

Para efectos que solo deben ocurrir una vez, como animaciones de entrada:

.fade-in {
  animation-name: fadeIn;
  animation-duration: 1s;
  animation-iteration-count: 1; /* Valor por defecto */
  animation-direction: normal; /* Valor por defecto */
}

Animaciones continuas

Para elementos que deben animarse constantemente, como indicadores de carga:

.spinner {
  animation-name: rotate;
  animation-duration: 1.5s;
  animation-iteration-count: infinite;
  animation-direction: normal;
}

Animaciones de ida y vuelta

Para efectos que deben moverse suavemente entre dos estados:

.breathe {
  animation-name: breathe;
  animation-duration: 4s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

Consideraciones de rendimiento

Al trabajar con animaciones que se repiten muchas veces o indefinidamente, es importante considerar el rendimiento:

  • Las animaciones que modifican propiedades como transform y opacity son más eficientes que las que cambian width, height o background-color.
  • Para dispositivos móviles o con recursos limitados, considera usar valores más bajos de animation-iteration-count o implementar pausas en animaciones infinitas cuando el elemento no esté visible.
/* Más eficiente */
@keyframes efficient {
  from { transform: translateX(0); opacity: 1; }
  to { transform: translateX(100px); opacity: 0.5; }
}

/* Menos eficiente */
@keyframes less-efficient {
  from { left: 0; background-color: red; }
  to { left: 100px; background-color: blue; }
}

Compatibilidad entre navegadores

Estas propiedades tienen buen soporte en navegadores modernos, pero para proyectos que requieran compatibilidad con navegadores más antiguos, considera usar la propiedad abreviada animation con prefijos de proveedor cuando sea necesario:

.element {
  -webkit-animation: bounce 2s infinite alternate;
  animation: bounce 2s infinite alternate;
}

La combinación de animation-iteration-count y animation-direction nos permite crear animaciones más complejas y naturales, controlando precisamente cómo y cuántas veces se ejecutan nuestras secuencias de keyframes. En la siguiente sección, exploraremos cómo controlar el estado final de nuestras animaciones con animation-fill-mode.

Estados de la animación con animation-fill-mode

Cuando trabajamos con animaciones en CSS, es importante controlar no solo cómo se comporta un elemento durante la animación, sino también qué sucede con él antes y después de que la animación se ejecute. Aquí es donde entra en juego la propiedad animation-fill-mode, que nos permite definir cómo se aplicarán los estilos de la animación fuera del tiempo de ejecución de la misma.

Por defecto, una animación solo afecta al elemento mientras se está ejecutando. Esto significa que antes de comenzar y después de terminar, el elemento mantiene sus estilos originales. Sin embargo, en muchas situaciones, necesitamos que el elemento conserve el estado final de la animación o que adopte el estado inicial antes de comenzar.

Valores de animation-fill-mode

La propiedad animation-fill-mode acepta cuatro valores posibles:

  • none: Es el valor predeterminado. Los estilos de la animación no afectan al elemento antes o después de ejecutarse.
  • forwards: El elemento retendrá los valores establecidos en el último keyframe cuando la animación termine.
  • backwards: El elemento aplicará los valores del primer keyframe antes de que comience la animación.
  • both: Combina los efectos de forwards y backwards.

Veamos cómo funciona cada uno de estos valores en la práctica:

Valor none (predeterminado)

@keyframes slide-up {
  from {
    transform: translateY(50px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.element {
  animation-name: slide-up;
  animation-duration: 1s;
  animation-fill-mode: none;
}

Con none, el elemento:

  • Mantiene sus estilos originales antes de que comience la animación
  • Se anima durante la duración especificada
  • Vuelve a sus estilos originales inmediatamente después de que termine la animación

Este comportamiento puede crear un efecto de parpadeo no deseado, especialmente si la animación modifica propiedades como la opacidad o la posición.

Valor forwards

.element {
  animation-name: slide-up;
  animation-duration: 1s;
  animation-fill-mode: forwards;
}

Con forwards, el elemento:

  • Mantiene sus estilos originales antes de que comience la animación
  • Se anima durante la duración especificada
  • Conserva los valores del último keyframe después de que termine la animación

Este valor es especialmente útil para:

  • Animaciones de entrada donde queremos que el elemento permanezca visible
  • Transiciones de estado donde el estado final es el deseado
  • Animaciones que revelan contenido que debe permanecer en su posición final

Valor backwards

.element {
  animation-name: slide-up;
  animation-duration: 1s;
  animation-delay: 2s;
  animation-fill-mode: backwards;
}

Con backwards, el elemento:

  • Adopta los valores del primer keyframe antes de que comience la animación (incluso durante un retraso)
  • Se anima durante la duración especificada
  • Vuelve a sus estilos originales después de que termine la animación

Este valor es particularmente útil cuando:

  • Tenemos animaciones con animation-delay
  • Queremos que el elemento adopte su estado inicial de animación inmediatamente, incluso antes de comenzar
  • Estamos coordinando múltiples animaciones con diferentes tiempos de inicio

Valor both

.element {
  animation-name: slide-up;
  animation-duration: 1s;
  animation-delay: 2s;
  animation-fill-mode: both;
}

Con both, el elemento:

  • Adopta los valores del primer keyframe antes de que comience la animación
  • Se anima durante la duración especificada
  • Conserva los valores del último keyframe después de que termine la animación

Este es el valor más completo y es ideal para:

  • Animaciones con retraso que también deben mantener su estado final
  • Secuencias de animación complejas donde necesitamos control total sobre los estados
  • Situaciones donde queremos evitar cualquier "salto" visual antes o después de la animación

Ejemplos prácticos

Ejemplo 1: Animación de entrada con permanencia

@keyframes fade-in {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.notification {
  background-color: #e3f2fd;
  padding: 15px;
  border-radius: 4px;
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
  
  /* Configuración de la animación */
  animation-name: fade-in;
  animation-duration: 0.5s;
  animation-fill-mode: forwards;
}

En este ejemplo, la notificación aparece gradualmente y permanece visible gracias a forwards. Sin este valor, la notificación desaparecería después de completar la animación.

Ejemplo 2: Secuencia de animación con retraso

@keyframes circle-grow {
  from {
    transform: scale(0);
    background-color: #ff5252;
  }
  to {
    transform: scale(1);
    background-color: #2196f3;
  }
}

.circle-1, .circle-2, .circle-3 {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  
  animation-name: circle-grow;
  animation-duration: 0.8s;
  animation-fill-mode: both;
}

.circle-1 {
  animation-delay: 0s;
}

.circle-2 {
  animation-delay: 0.3s;
}

.circle-3 {
  animation-delay: 0.6s;
}

En este ejemplo, tres círculos se animan en secuencia. Gracias a animation-fill-mode: both, cada círculo:

  • Comienza invisible (escala 0) incluso durante su retraso
  • Crece y cambia de color durante la animación
  • Permanece en su tamaño completo y color final después de la animación

Ejemplo 3: Botón con efecto hover persistente

@keyframes button-highlight {
  from {
    background-color: #4caf50;
    box-shadow: 0 2px 5px rgba(0,0,0,0.2);
  }
  to {
    background-color: #45a049;
    box-shadow: 0 4px 8px rgba(0,0,0,0.3);
  }
}

.action-button:hover {
  animation-name: button-highlight;
  animation-duration: 0.3s;
  animation-fill-mode: forwards;
}

En este ejemplo, cuando el usuario pasa el cursor sobre el botón, este cambia de color y aumenta su sombra. Con forwards, estos cambios permanecen mientras el cursor esté sobre el botón, creando una experiencia más fluida.

Combinación con otras propiedades de animación

La propiedad animation-fill-mode funciona en conjunto con otras propiedades de animación para crear efectos más complejos:

.element {
  animation-name: bounce;
  animation-duration: 1s;
  animation-timing-function: ease-out;
  animation-delay: 0.5s;
  animation-iteration-count: 2;
  animation-direction: alternate;
  animation-fill-mode: both;
}

En este ejemplo completo:

  1. La animación comienza después de un retraso de 0.5 segundos
  2. Durante este retraso, el elemento ya muestra el estado inicial de la animación (gracias a both)
  3. La animación se ejecuta dos veces, alternando dirección
  4. Después de completarse, el elemento mantiene el estado del último keyframe ejecutado

Consideraciones importantes

  • Dirección de la animación: Cuando usas forwards con animation-direction: reverse o alternate, el "último keyframe" será el primero definido en tu regla @keyframes.
@keyframes slide {
  from { transform: translateX(0); }
  to { transform: translateX(100px); }
}

.element {
  animation: slide 1s forwards reverse;
  /* El elemento terminará en translateX(0) */
}
  • Múltiples animaciones: Cuando aplicas varias animaciones a un elemento, cada una puede tener su propio valor de animation-fill-mode:
.element {
  animation-name: fade, scale;
  animation-duration: 1s, 2s;
  animation-fill-mode: forwards, none;
}
  • Reinicio de animaciones: Si necesitas reiniciar una animación con forwards, deberás eliminar y volver a aplicar la animación, o cambiar su nombre temporalmente.

Uso en interfaces modernas

La propiedad animation-fill-mode es fundamental para crear interfaces fluidas y profesionales:

  • Menús desplegables: Usa forwards para mantener el menú visible después de la animación de apertura.
  • Cargas progresivas: Utiliza both para elementos que aparecen secuencialmente en la página.
  • Transiciones entre estados: Emplea forwards para mantener el nuevo estado después de una transición animada.
.accordion-content {
  max-height: 0;
  overflow: hidden;
  
  animation-name: expand;
  animation-duration: 0.3s;
  animation-fill-mode: forwards;
}

@keyframes expand {
  from {
    max-height: 0;
    opacity: 0;
  }
  to {
    max-height: 200px;
    opacity: 1;
  }
}

En este ejemplo de un acordeón, el contenido se expande y permanece visible gracias a forwards. Sin este valor, el contenido se colapsaría nuevamente después de la animación.

La propiedad animation-fill-mode es una herramienta poderosa que nos permite controlar con precisión el comportamiento de nuestras animaciones antes y después de su ejecución, creando transiciones más suaves y experiencias de usuario más coherentes.

CONSTRUYE TU CARRERA EN IA Y PROGRAMACIÓN SOFTWARE

Accede a +1000 lecciones y cursos con certificado. Mejora tu portfolio con certificados de superación para tu CV.

Plan mensual

19.00 € /mes

Precio normal mensual: 19 €
47 % DE DESCUENTO

Plan anual

10.00 € /mes

Ahorras 108 € al año
Precio normal anual: 120 €
Aprende CSS online

Ejercicios de esta lección Animaciones

Evalúa tus conocimientos de esta lección Animaciones con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Todas las lecciones de CSS

Accede a todas las lecciones de CSS y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Css

CSS

Introducción Y Entorno

Entorno Para Desarrollar Css

CSS

Introducción Y Entorno

Sintaxis

CSS

Sintaxis De Selectores Y Propiedades

Selectores Básicos

CSS

Sintaxis De Selectores Y Propiedades

Herencia Y Cascada

CSS

Sintaxis De Selectores Y Propiedades

Pseudo-clases Y Pseudo-elementos

CSS

Sintaxis De Selectores Y Propiedades

Colores En Css

CSS

Sintaxis De Selectores Y Propiedades

Unidades De Medida

CSS

Sintaxis De Selectores Y Propiedades

Especificidad

CSS

Sintaxis De Selectores Y Propiedades

Estilos De Fuente

CSS

Estilización De Texto Y Fondo

Propiedades De Texto

CSS

Estilización De Texto Y Fondo

Sombras En Texto Y Cajas

CSS

Estilización De Texto Y Fondo

Propiedades De Fondo

CSS

Estilización De Texto Y Fondo

Fuentes Web

CSS

Estilización De Texto Y Fondo

Efectos De Texto: Gradientes, Recortes

CSS

Estilización De Texto Y Fondo

Tipografía Avanzada

CSS

Estilización De Texto Y Fondo

Modelo De Caja

CSS

Modelo Caja

Propiedades De Posicionamiento

CSS

Modelo Caja

Propiedad 'Display'

CSS

Modelo Caja

Elementos 'Float' Y 'Clear'

CSS

Modelo Caja

Rellenos Y Márgenes

CSS

Modelo Caja

Bordes Y Contornos

CSS

Modelo Caja

Absolute, Fixed, Sticky Y Z-index

CSS

Posicionamiento

Flexbox Para Crear Layouts Y Estructuras

CSS

Flexbox

Css Grid Para Crear Layouts Y Estructuras

CSS

Flexbox

Propiedades Del Contenedor Flex

CSS

Flexbox

Propiedades De Los Items Flex

CSS

Flexbox

Columnas Y Filas En Grid

CSS

Css Grid

Espaciado Y Alineación

CSS

Css Grid

Tipografía Responsive

CSS

Diseño Responsive

Fundamentos Del Diseño Responsive

CSS

Diseño Responsive

Imágenes Responsive

CSS

Diseño Responsive

Funciones Matemáticas

CSS

Variables Y Funciones Css

Transformaciones 2d

CSS

Transformación, Transición, Animación

Transformaciones 3d

CSS

Transformación, Transición, Animación

Animaciones

CSS

Transformación, Transición, Animación

Transiciones

CSS

Transformación, Transición, Animación

Css Para Formularios

CSS

Css Avanzado

Accesibilidad Web Con Css

CSS

Css Avanzado

Container Queries

CSS

Css Avanzado

Selectores Avanzados

CSS

Css Avanzado

Animaciones Y Transiciones

CSS

Técnicas Modernas Y Metodologías

Variables En Css

CSS

Técnicas Modernas Y Metodologías

Diseño Responsive Con Media Queries

CSS

Técnicas Modernas Y Metodologías

Metodologías De Escritura En Css

CSS

Técnicas Modernas Y Metodologías

Accede GRATIS a CSS y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender la definición y uso de la regla @keyframes para crear animaciones en CSS.
  • Aprender a aplicar animaciones a elementos HTML usando animation-name y animation-duration.
  • Controlar la repetición y dirección de las animaciones con animation-iteration-count y animation-direction.
  • Gestionar el estado inicial y final de las animaciones mediante animation-fill-mode.
  • Reconocer buenas prácticas y consideraciones de rendimiento y compatibilidad en animaciones CSS.