Animando con CSS3: keyframes y animation

Animación en fotogramas
Imagen de Juliana - modificada.

Las animaciones son un gran arma cuando intentamos captar la atención del usuario en aquellas zonas de la web que estimamos de vital importancia. Porque a fin de cuentas somos simples, muy simples, y nos encantan las cosas brillantes y todo aquello que se mueva.

En animación web siempre hemos tenido que recurrir a otros lenguajes para este tipo de usos, sobre todo Javascript, pero CSS3 ha cambiado todo esto. A parte de las animaciones simples que podemos realizar con transition, CSS3 nos da una herramienta mucho más potente, @keyframes, que nos permite realizar animaciones más complejas, con ciclos y la posibilidad de iniciarla y pararla. Por esto Javascript se ha ido relegando a un segundo plano. Así que no pierdas el tiempo, ha llegado el momento de crear animaciones con CSS3.

Las animaciones en CSS constan de dos grandes bloques:

  • Keyframes - con @keyframes definimos los estados y estilos de la animación.
  • Propiedades de la animación - en este bloque asignamos los @keyframes a una regla específica de nuestro CSS y definimos como va a ser animado el elemento de HTML seleccionado por nuestra regla.

Vamos a verlos con más detalle.

Las keyframes

Las keyframes son la parte fundamental de la animación. Con ellas definimos cómo se verá la animación en cada estado de la línea de tiempo (timeline). Cada @keyframes se compone de:

  • Nombre de la animación: Un nombre que describa la animación (esto es sólo un consejo) que luego va a ser usado en la propiedades de la animación mediante la propiedad animation-name.
  • Estados de la animación: cada animación debe poseer al menos dos estados, uno para el inicio y otro para el final. Estos estados se representan mediante un porcentaje, 0% para el inicio y 100% para el final, aunque para estos dos estados también podemos usar las palabras reservadas from y to. Entre medias podemos añadir tantos estados como queramos, siempre expresados en porcentajes.
  • Propiedades de CSS: Las propiedades de CSS definidas para cada estado de la animación en la línea de tiempo.

Para que quede más claro vamos con un ejemplo que iremos construyendo poco a poco en este tutorial. Va a ser algo muy sencillo, tan sólo una caja que se mueve de izquierda a derecha y viceversa, de forma infinita. Este es el @keyframes que vamos a usar:


@keyframes moving-box {
  0% {left:10%}
  100% {left:80%}
}

Las propiedades de la animación

Ahora que ya tenemos creado nuestro @keyframes tenemos que añadir las propiedades de la animación para darle funcionalidad. Como ya vimos con ellas haremos dos cosas: asignamos las @keyframes al elemento que queremos animar y definimos cómo será animado.

Las propiedades de la animación las asignaremos a una regla CSS del elemento que queremos animar. Como mínimo debemos definir al menos dos propiedades animation-name y animation-duration. Por supuesto hay más propiedades CSS, en concreto seis, lo que da un total de ocho propiedades. Vamos a verlas de forma resumida para que te hagas una idea de lo que podemos hacer con ellas:

  • animation-name: El nombre de la animación, que previamente hemos definido en las @keyframes.
  • animation-duration: Con esta propiedad definimos el tiempo que durará la animación, expresado bien en segundos(s) o en milisegundos(ms).
  • animation-timing-function: Define la curva de velocidad o ritmo de la animación. Podemos definirla con las palabras reservadas ease, linear, ease-in, ease-out, ease-in-out, initial e inherit, o de forma más compleja mediante la curva de Bézier. El valor por defecto (si no le damos otro) es ease. Si en alguna ocasión has trabajado con transition seguro que ya las conoces.
  • animation-delay: Permite definir cuando comenzará la animación. Si es un valor positivo la animación comenzará en el instante que hayamos especificado. Si por el contrario el valor es negativo, la animación comenzará inmediatamente, pero ya habrá pasado el tiempo que hayamos especificado, es decir, nos perderemos el trozo de animación correspondiente al tiempo que hayamos dado. El valor se puede expresar tanto en segundos(s) como en milisegundos(ms). La propiedad animation-delay es muy útil cuando queremos concatenar varias animaciones.
  • animation-iteration-count: Aquí definimos el número de veces que la animación se va a ejecutar. Los valores que puede tomar son:
    • #: Un valor numérico (por defecto es 1).
    • infinite: La animación se repite de forma recursiva.
    • initial: Establece el número de iteraciones en el valor predeterminado.
    • inherit: Hereda el valor de su padre.
  • animation-direction: Especifica si la animación se ejecutará hacia adelante, hacia atrás o en ciclos alternos (hacia adelante y hacia atrás). Los valores que puede tomar son:
    • normal: Es el estado por defecto. La animación se ejecuta hacia adelante y en cada ciclo vuelve a empezar desde el estado inicial (0%).
    • reverse: La animación se ejecuta hacia atrás, por tanto en cada ciclo empieza desde su estado final (100%).
    • alternate: La animación cambia de sentido en cada ciclo. Así en los ciclos impares lo hará hacia adelante y el los ciclos pares lo hará hacia atrás.
    • reverse-alternate: Parecido al estado anterior pero justo al revés. En los ciclos impares lo hará hacia atrás y en los ciclos pares hacia adelante.
  • animation-fill-mode: Especifica si los estilos de la animación son visibles antes o después que esta comience. Por defecto la animación no afecta a los estilos del elemento antes que esta comience o una vez que esta haya terminado. Con esta propiedad podemos cambiar estos valores:
    • backwards: Antes de que comience la animación los estilos del keyframe inicial (0%) son aplicados al elemento.
    • forwards: Una vez acabada la animación los estilos aplicados por la animación en el keyframe final (100%) se mantienen aplicados.
    • both: La animación aplica las dos reglas anteriores, aplicando los estilos antes de que la animación comience y también después que haya finalizado.
    • normal: Es el estado por defecto. Los estilos sólo se aplican al elemento mientras la animación está en curso.
  • animation-play-state: Con esta propiedad determinamos cuando la animación está en curso o en pausa. Los valores que puede tomar son running (aunque también funciona con playing) y paused

Al igual que en otras propiedades CSS tenemos una forma abreviada, que es la que se aconseja usar siempre que sea posible:

animation: [animation-name] [animation-duration] [animation-timing-function] [animation-delay] [animation-iteration-count] [animation-direction] [animation-fill-mode] [animation-play-state];

La animación

Ahora que ya hemos visto las posibilidades que tenemos con las propiedades animation, es momento de ponerlo todo es práctica. Anteriormente ya habíamos definidos las @keyframes para nuestra animación, ahora es momento de puntualizar un poco más que es lo que vamos a hacer.

Como dije va a ser muy sencilla. Vamos a hacer una animación cíclica e infinita en el tiempo. Moveremos una caja de izquierda a derecha y viceversa, y tendremos otra caja adicional, centrada en la pantalla, que nos permitirá pausar la animación al pasar el cursor sobre ella (usaremos el selector de adyacentes). si has llegado hasta aquí seguro que sabes como hacerla:


#caja1, #caja2 {
  width: 8em;
  height: 8em;
  position: absolute;
  top: 3em;
}

#caja1 {
  background: rgba(0,0,255,.5);
  left: 45%;
  text-align: center;
  line-height: 8em;
  color: #fff;
  z-index: 10;
}

#caja2 {
  left:10%;
  background: rgba(255,0,0,.5);
  animation: moving-box 5s infinite alternate running;
}

#caja1:hover + #caja2 {
  animation-play-state: paused;
}

See the Pen Cajas en movimiento con CSS by amram (@amram1977) on CodePen.