Animaciones CSS

Una vez conocemos las transiciones CSS, es muy fácil adaptarnos al concepto de animaciones de CSS, el cual amplia el concepto de transiciones convirtiéndolo en algo mucho más flexible y potente.

Las transiciones son una manera de suavizar un cambio de un estado inicial a un estado final. La idea de las animaciones CSS parte del mismo concepto, permitiendo añadir más estados, pudiendo realizar cambios desde un estado inicial, a un estado posterior, a otro estado posterior, y así sucesivamente. Además, esto será posible de forma automática, sin que el usuario tenga que realizar una acción concreta.

El primer paso para crear animaciones es tener dos cosas claras. Por un lado, utilizaremos la regla @keyframes, que incluye los fotogramas de la animación. Por otro lado, tendremos que utilizar las propiedades de las animaciones, que definen el comportamiento de la misma.

Propiedades de animación CSS

Para definir dicho comportamiento necesitamos conocer las siguientes propiedades, que son una ampliación de las transiciones CSS:

Propiedades Valor
animation-name none | nombre
animation-duration 0 |
animation-timing-function ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(A, B, C, D)
animation-delay 0 |
animation-iteration-count 1 | infinite |
animation-direction normal | reverse | alternate | alternate-reverse
animation-fill-mode none | forwards | backwards | both
animation-play-state running | paused

La propiedad animation-name permite especificar el nombre del fotograma a utilizar, mientras que las propiedades animation-duration, animation-timing-function y animation-delay funcionan exactamente igual que en el tema anterior de transiciones.

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. 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 de los siguientes:

Valor Significado
normal Los fotogramas se reproducen desde el principio al final.
reverse Los fotogramas se reproducen desde el final al principio.
alternate En iteraciones par, de forma normal. Impares, a la inversa.
alternate-reverse En iteraciones impares, de forma normal. Pares, normal.

Por defecto, cuando se termina una animación que se ha indicado que se reproduzca sólo una vez, la animación vuelve a su estado inicial (primer fotograma). Mediante la propiedad animation-fill-mode podemos indicar que debe mostrar la animación cuando ha finalizado y ya no se está reproduciendo; si mostrar el estado inicial (backwards), el estado final (forwards) o una combinación de ambas (both).

Por último, la propiedad animation-play-state nos permite establecer la animación a estado de reproducción (running) o pausarla (paused).

Atajo: Animaciones

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

div {
  /* animation: <name> <duration> <timing-function> <delay>
                <iteration-count> <direction> <fill-mode> <play-state> */
  animation: changeColor 5s linear 0.5s 4 normal forwards running;
}

Consejo: Mucho cuidado al indicar los segundos en las propiedades de duración. Al ser una unidad diferente a las que solemos manejar (px, em, etc...) hay que especificar siempre la s, aunque sea un valor igual a 0.

Fotogramas (keyframes)

Ya sabemos como indicar a ciertas etiquetas HTML que reproduzcan una animación, con ciertas propiedades. Sin embargo, nos falta la parte más importante: definir los fotogramas de dicha animación. Para ello utilizaremos la regla @keyframes, la cuál es muy sencilla de utilizar y se basa en el siguiente esquema:

Sintaxis del esquema de los keyframes

En primer lugar elegiremos un nombre para la animación (el cuál utilizamos en el apartado anterior, para hacer referencia a la animación, ya que podemos tener varias en una misma página), mientras que podremos utilizar varios selectores para definir el transcurso de los fotogramas en la animación.

Veamos algunos ejemplos:

@keyframes changeColor {
  from { background: red; }  /* Primer fotograma */
  to { background: green; }  /* Último fotograma */
}

.anim {
  background: grey;
  color: #FFF;
  width: 150px;
  height: 150px;
  animation: changeColor 2s ease 0 infinite;  /* Relaciona con @keyframes */
}

En este ejemplo nombrado changeColor, partimos de un primer fotograma en el que el elemento en cuestión será de color de fondo rojo. Si observamos el último fotograma, le ordenamos que termine con el color de fondo verde. Así pues, la regla @keyframes se inventará la animación intermedia para conseguir que el elemento cambie de color.

Los selectores from y to son realmente sinónimos de 0% y 100%, así que los modificaremos y de esta forma podremos ir añadiendo nuevos fotogramas intermedios. Vamos a modificar el ejemplo anterior añadiendo un fotograma intermedio e indentando, ahora sí, correctamente el código:

@keyframes changeColor {
  0% {
    background: red;         /* Primer fotograma */
  }
  50% {
    background: yellow;      /* Segundo fotograma */
    width: 400px;
  }
  100% {
    background: green;       /* Último fotograma */
  }
}

.anim {
  background: grey;
  color: #FFF;
  width: 150px;
  height: 150px;
  animation: changeColor 2s ease 0 infinite;  /* Relaciona con @keyframes */
}

Truco: Si tienes fotogramas que van a utilizar los mismos estilos que uno anterior, siempre puedes separarlos con comas, por ejemplo: 0%, 75% { ... }, que utilizarían dichos estilos al inicio de la animación y al 75% de la misma.

Encadenar animaciones

Es posible encadenar múltiples animaciones, separando con comas las animaciones individuales y estableciendo un tiempo de tardo a cada animación posterior:

.animated {
  animation:
    moveRight 5s linear 0,    /* Comienza a los 0s */
    lookUp 2.5s linear 5s,    /* Comienza a los 5s */
    moveLeft 5s linear 7.5s,  /* Comienza a los 7.5s (5 + 2.5) */
    dissapear 2s linear 9.5s; /* Comienza a los 9.5s (5 + 2.5 + 2) */
}

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.

Manz
Publicado por Manz

Docente, divulgador informático y freelance. Autor de Emezeta.com, es profesor en la Universidad de La Laguna y dirige el curso de Programación web FullStack y Diseño web FrontEnd de EOI en Tenerife (Canarias). En sus ratos libres, busca GIF de gatos en Internet.