Animaciones CSS

Propiedades para crear animaciones en CSS


Una vez conocemos las transiciones CSS, es muy fácil adaptarnos al concepto de animaciones CSS, el cual amplia lo que ya sabemos de transiciones, convirtiéndolo en algo mucho más flexible y potente, en el que no es necesario que el usuario interactue de alguna forma (cómo pasa en las transiciones).

Las transiciones son una manera de suavizar un cambio de un estado inicial a un estado final. La idea de las animaciones CSS parten del mismo concepto, pero a diferencia de las transiciones, permiten añadir más estados aún. Así pues, con las animaciones podemos partir desde un estado inicial, a un estado posterior, a otro estado posterior, y así sucesivamente.

Para crear animaciones CSS es necesario realizar 2 pasos:

  • Utilizar la propiedad animation (o derivadas) para indicar que elemento HTML vamos a animar.
  • Definir mediante la regla @keyframes la animación en cuestión y sus estados (fotogramas clave).

En primer lugar, vamos a examinar las diferentes propiedades relacionadas con las animaciones, y más adelante veremos como crear fotogramas con la regla @keyframes.

Propiedades de animación CSS

Para el comportamiento de una animación, necesitamos conocer las siguientes propiedades, que son una «ampliación» de las propiedades de las transiciones CSS:

Propiedades Descripción Valor
animation-name Nombre de la animación a aplicar. none | nombre
animation-duration Duración de la animación. 0 |
animation-timing-function Ritmo de la animación. Ver funciones de tiempo
animation-delay Retardo en iniciar la animación. 0 |
animation-iteration-count Número de veces que se repetirá. 1 | infinite |
animation-direction Dirección de la animación. normal | reverse | alternate | alternate-reverse
animation-fill-mode Como se «completa» la animación. none | forwards | backwards | both
animation-play-state Estado de la animación. running | paused
animation-composition Como se «mezclan» varias animaciones. replace | add | accumulate
animation-timeline Define una línea de tiempo animada. Ver animaciones de scroll

En las siguientes secciones explicaremos detenidamente cada una de estas propiedades y su funcionamiento.

Nombre de la animación

La propiedad principal de las animaciones es animation-name, ya que esta permite especificar el nombre de la animación (definido con la regla @keyframes que veremos más adelante) que queremos asociar al elemento HTML donde indicamos la propiedad. El nombre de la animación debería estar en kebab-case (y no en camelCase u otras).

  • La propiedad animation-duration establece el tiempo de duración de la animación.
  • La propiedad animation-delay establece el retardo en empezar la animación.
  • La propiedad animation-timing-function establece el ritmo de la animación.

Las propiedades animation-duration y animation-delay funcionan exactamente igual que las propiedades análogas transition-duration y transition-delay del apartado de Transiciones CSS. De igual forma, la propiedad animation-timing-function es idéntica a la propiedad transition-timing-function que explicamos en el apartado de Funciones de tiempo.

Número de repeticiones

La propiedad animation-iteration-count permite indicar el número de veces que se repite la animación, pudiendo establecer un número concreto de repeticiones o indicando infinite para que se repita continuamente.

Dirección de la animación

Por otra parte, especificando un valor en animation-direction conseguiremos indicar el orden en el que se reproducirán los fotogramas, pudiendo escoger un valor entre los siguientes:

Valor Significado
normal Los fotogramas se reproducen en orden: desde el primero hasta el último.
reverse Los fotogramas se reproducen en orden inverso: desde el final hasta el primero.
alternate En iteraciones par, se reproducen como normal. En impares, como reverse.
alternate-reverse En iteraciones par, se reproducen como reverse. En impares, como normal.

Modo de completado

Por defecto, una animación antes de arrancar y después de terminar (si no está establecida en repetición infinite) no tiene aplicados los estilos de la animación especificada en cuestión. Esto se puede ver fácilmente, por ejemplo, cuando termina una animación, que vuelve a sus «estilos iniciales».

Mediante la propiedad animation-fill-mode podemos indicar que debe hacer la animación cuando no se está reproduciendo:

  • El valor none realiza el comportamiento indicado en el párrafo anterior.
  • El valor backwards indica que la animación debe tener aplicados los estilos del fotograma inicial antes de empezar.
  • El valor forwards indica que la animación debe tener aplicados los estilos del fotograma final al terminar.
  • El valor both indica que debe aplicar los dos casos anteriores (backwards y forwards).

Estado de la animación

Por último, la propiedad animation-play-state nos permite establecer la animación a estado de reproducción running o pausarla mediante el valor paused. Esto en CSS no da demasiadas posibilidades, pero puede ser muy útil combinado con algo de Javascript.

Atajo: Animaciones

Nuevamente, CSS ofrece la posibilidad de resumir todas estas propiedades en una sola, para hacer nuestras hojas de estilos más compactas. El orden recomendado para los valores de la propiedad de atajo sería el siguiente:

.animated {
  /* animation: <name> <duration> <timing-function> <delay>
                <iteration-count> <direction> <fill-mode> <play-state> */

  animation:
    change-color 5s linear 0.5s 4 normal forwards running;
}

OJO: Mucho cuidado al indicar los segundos en las propiedades animation-duration y/o animation-delay. Si no indicamos la unidad (incluso con valores de cero), se interpretará como el valor de la propiedad animation-iteration-count, que es el número de veces que se repite la animación (y no lleva unidad).

Animaciones múltiples

Como en muchas propiedades de CSS, es posible separar por comas para indicar múltiples valores, en este caso, para indicar que queremos realizar varias animaciones a la vez. En este ejemplo, indicamos que tanto la animación move-right como la animación change-color deben empezar a la vez, cada una de las cuales dura 5 segundos y tienen un ritmo lineal (constante):

.animated {
  animation:
    move-right 5s linear,
    change-color 5s linear;
}

Sin embargo, si además añadimos la propiedad animation-delay, podemos hacer algo muy interesante.

Encadenar animaciones

Es posible encadenar animaciones utilizando animaciones múltiples combinadas con la propiedad animation-delay. Observa el siguiente ejemplo donde se verá mucho mejor:

.animated {
  animation:
    move-right 5s linear 0s,   /* Comienza a los 0s (no hay anterior) */
    look-up 2.5s linear 5s,    /* Comienza a los 5s (5 de la anterior) */
    move-left 5s linear 7.5s,  /* Comienza a los 7.5s (5 + 2.5 de la anterior) */
    dissapear 2s linear 9.5s;  /* Comienza a los 9.5s (5 + 2.5 + 2 de la anterior) */
}

El truco de este ejemplo está en los valores de duración y los de retardo, en combinación con los anteriores:

  • La primera animación move-right comienza a los 0 segundos y dura 5 segundos.
  • La segunda animación look-up comienza a los 5 segundos y dura 2.5 segundos.
  • La tercera animación move-left comienza a los 7.5 segundos y dura 5 segundos.
  • La cuarta animación dissapear comienza a los 9.5 segundos y dura 2 segundos.

En este caso, lo que hemos hecho es aplicar varias animaciones a la vez, pero estableciendo un retardo (cuarto parámetro) que es la suma de la duración de las animaciones anteriores. De esta forma, encadenamos una animación con otra.

Composición de animaciones

Mediante la propiedad animation-composition podemos indicar al navegador como se van a aplicar por parte del navegador múltiples animaciones. Los valores disponibles a utilizar son los siguientes:

Valor Descripción
replace Las animaciones se sobreescriben. Valor por defecto.
add Las animaciones se añaden.
accumulate Las animaciones se acumulan.

Pero para ver esto más claro, lo mejor es aplicar un ejemplo y entender su funcionamiento. Observa el siguiente fragmento de código. En él encontrarás un cuadrado con las siguientes características:

  • Inicialmente, su color es gris
  • Aplica una animación de movimiento move durante 3s
  • Luego, aplica una animación de rotación durante 3s.
  • A partir de ahí, se repiten simultáneamente.
  • Además, cada animación cambia el color del cuadrado.
.item {
  width: 100px;
  height: 100px;
  background: grey;
  animation:
    move 3s infinite 0s,
    rotate 3s infinite 3s;
  animation-composition: replace;
}

@keyframes move {
  to {
    transform: translateX(500px);
    background: red;
  }
}

@keyframes rotate {
  to {
    transform: rotate(360deg) scale(0.5);
    background: indigo;
  }
}

Ahora, analicemos las animaciones:

  • La animación move traslada el elemento 500px a la derecha y cambia a rojo.
  • La animación rotate rota el elemento mientras lo que hace la mitad más pequeño. Cambia a lila.

Ahora observemos como se comporta según el valor que apliquemos de animation-composition. Nos centraremos en las iteraciones finales donde se aplican tanto move como rotate:

  • Con el valor replace la animación comienza trasladándose como dicta move, pero a mitad de cambio es reemplazada por rotate. Observa que se aprecia ligeramente el cambio a rojo que termina modificandose por lila.

  • Con el valor add notamos que los colores se mezclan (gris + rojo + lila) y no se reemplazan. Por otro lado, en este caso las animaciones se han sumado, el trayecto de translateX() se hace completo, al igual que el rotate() y el scale().

  • Con el valor accumulate pasa igual con los colores, sin embargo, con las animaciones en este caso no se aplica la rotación, ya que en la primera animación no existe rotate().

Ten en cuenta que en el caso de translate() y scale(), los valores iniciales aunque no están indicados se infieren por parte del navegador, ya que un elemento sin trasladar es equivalente a translate(0, 0) y un elemento sin escalar es equivalente a scale(1). No ocurre lo mismo con la rotación rotate().

En el caso de querer aplicar composiciones diferentes por cada animación, separaremos por coma, como solemos hacer habitualmente.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev