Logo de Mosaic
Temas de CSS
Mover las cosas con animaciones CSS

Mover las cosas con animaciones CSS

Chris David Mills. 25 de abril de 2012. Artículo original en inglés

Introducción

Tradicionalmente, la web era un lugar muy estático. Animace no era posible de ninguna manera cuerda hasta la llegada de JavaScript, los GIFs animados y Flash, momento en el que nos regocijamos y aplaudimos la gran cantidad resultante de 'saltar intro' y horribles animaciones molestas.

Estaba todo muy bien, pero seguía sin haber manera para que los no desarrolladores creasen animaciones con estándares abiertos. Puedes dar salida a todos los argumentos religiosos que desees sobre que la animación que pertenece a la capa de comportamiento, y no a la capa de presentación, pero creo que la animación definitivamente cae en el ámbito del diseño. Y ahora, con las transiciones y animaciones CSS3, se pueden animar los elementos de nuestro sitio web. ¡Diseño web basado en estándares con más diversión! Y más 'saltar intro', si lo prefieres…

Opera tiene soporte para transiciones desde hace mucho tiempo, y ya hemos escrito sobre ellos en CSS3 transitions and 2D transforms. Este artículo se centra en la otra manera de animar las cosas usando hojas de estilo: las animaciones CSS. A continuación daremos una introducción concreta incluyendo el estado de la especificación y el soporte en navegadores, las diferencias entre animaciones y transiciones, la sintaxis básica, y una lista de ejemplos.

¿Es una tecnología madura?

La especificación de animaciones CSS, propuesta y editada por Apple, se encuentra actualmente en estado de Borrador de Trabajo y se etiqueta como "Anticuado" en la página de trabajo actual del grupo de trabajo de CSS, así que podemos esperar ver algunos cambios menores antes de que finalice, pero el principio básico debería mantenerse.

En cualquier caso, ya se ha aplicado experimentalmente en Firefox (desde la versión 5), Chrome (desde la 4), Safari (desde la 4), IE (en la versión 10) y Opera desde la versión 12. Nótese el "experimentalmente": esto significa que es necesario utilizar los prefijos apropiados de proveedor para cada navegador.

Sintaxis básica

Las animaciones difieren de las transiciones en que las transiciones sólo se activan cuando se produce un cambio de estado (al poner el ratón sobre un elemento, por ejemplo), mientras que las animaciones se pueden activar independientemente de un cambio de estado, por lo general un período de tiempo después de cargar una página, o un evento a través de JavaScript. Además, una animación de transición siempre se produce en cualquiera de las propiedades que cambian sus valores cuando se produce un cambio de estado, mientras que una animación CSS puede animar valores de la propiedad, incluso si esas propiedades no se establecen en el estado por defecto del elemento que se está animando.

Definir una animación

Para configurar una animación, primero hay que definir algunos fotogramas clave, en un nuevo de reglas, de esta forma:

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

Aquí se nos dice que esta animación se llama "spin", y lo que hace es girar suavemente 360 grados el elemento al que se aplique. Ninguna otra cosa se define aquí, y puede sonar escaso, pero en realidad resulta muy flexible, ya que se puede definir una animación una vez y luego aplicarla a muchos elementos diferentes, con diferentes duraciones y otros comportamientos.

También se puede utilizar 0% y 100% en lugar de from y to. Si se desea, pueden incluirse fotogramas clave intermedios, para animaciones más complejas:

@keyframes spin {
  0% { transform: rotate(0deg); }
  25% { transform: rotate(30deg); }
  50% { transform: rotate(120deg); }
  100% { transform: rotate(360deg); }
}

Pueden escribirse fotogramas clave con los mismos valores en una sola línea, así:

25%, 50% {opacidad: 0,9;}

Nota

Puedes configurar la animación de manera que el primer fotograma clave no aparece en el 0% y lo haga, por ejemplo, en el 40%. Si lo haces, sin embargo, nada cambiará antes de ese punto en la animación. Si no se establece el último fotograma clave en un 100%, por ejemplo, 70%, la animación llegará a ese punto y permanecerá constante hasta el 100%.

Actualmente, la molestia principal de usar animaciones es que hay que definir un bloque de fotogramas clave diferente para cada navegador, ya que la propia regla utiliza un prefijo, y por tanto es necesario @-o-keyframes animation1 { }, @-moz-keyframes animation1 { }, etc. Y esto se suma a las diferentes versiones con prefijo de todas las propiedades de animación que veremos más adelante. Pero por lo menos dentro de cada regla con prefijo sólo es necesario incluir las propiedades individuales prefijadas para ese navegador, en el caso de propiedades que requieran prefijos. Y hay un par de librerías JavaScript que vale la pena estudiar, que detectan el motor de renderizado en tiempo de ejecución y añaden los prefijos apropiados cuando sea necesario, lo que ahorra tener que escribirlo todo. Véase Prefixfree, de Lea Verou, y Prefixr por Jeffrey Way.

Aplicar una animación

Para animar un elemento mediante esta animación, se aplican al elemento utilizando la propiedad animación-name:

#image {
  animation-name: spin;
}

Para hacer que esto haga algo, también hay que decir a la animación cuánto tiempo debe tomar para ejecutarse de principio a fin: esto se hace con antimation-duration:

#image {
  animation-name: spin;
  animation-duration: 3s;
}

Estas son todas las propiedades necesarias para que una animación se ejecute una vez sobre un elemento. Veamos ahora qué otras propiedades tenemos para controlar animaciones.

¿Cuántas veces queremos que suceda?

Para hacer que nuestra animación se ejecute un determinado número de veces, se utiliza animation-iteration-count:

#image {
  animation-name: spin;
  animation-duration: 3s;
  animation-iteration-count: 10;
}

El valor de animation-iteration-count puede ser cualquier número entero positivo, o puede ponerse a infinite para hacer que funcione eternamente. El valor predeterminado es 1.

Para ver lo que tenemos hasta ahora en acción, echa un vistazo a mi ejemplo de spinner básico.

Variar la tasa de animación

El primer ejemplo no tiene mal aspecto, pero veréis que en cada iteración de la animación el sol comienza a girar rápidamente y luego se desacelera hasta detenerse. Se puede modificar la velocidad de cambio de la animación estableciendo diferentes valores de la propiedad animation-timing-function. Los valores posibles son:

Nota

¿No entiendes las cúbicas de Bézier? Lea Verou ha creado una fantástica herramienta visual que permite visualizar fácilmente su significado, ver los efectos de diferentes valores de la función e incluso generar tus propios valores. Échale un vistazo en cubic-bezier.com/.

Para hacer que el giro del sol parezca más consistente, puse animation-timing-function a linear: carga spinner lineal para ver el resultado.

Nota

Para crear un efecto de "rebote", se puede utilizar una cúbica de Bézier con valores de control de arrastre superiores a los límites inferior o superior de la gráfica, como por ejemplo, cubic-bezier(.2,-0.36,.71,1.45)

Retrasos de animación

Se puede establecer un retardo antes de que comience la animación, estableciendo una propiedad animation-delay:

#image {
  animation-delay: 4s;
}

Esta propiedad puede tomar valores positivos y negativos. Un valor positivo retrasa el inicio de la animación, mientras que un valor negativo hace que la animación comience en parte hacia la duración de animación specificada. Normalmente se usa esta opción cuando tienes varias animaciones que deseas disparar en diferentes momentos para montar una secuencia completa.

¿De principio a fin, o de ida y vuelta?

Por defecto, las animaciones que se ejecutan varias veces van desde el principio hasta el final, luego saltan hasta el principio y van hasta el final de nuevo, y así sucesivamente. Pero puede hacerse que la animación se haga de ida y vuelta: de principio a fin, del final al inicio, de principio a fin, y así sucesivamente, especificando animation-direction: alternate; para el elemento que sea.

Para ver su efecto, echa un vistazo a mi ejemplo spinner alternativo. Ten en cuenta que el efecto de la función de tiempo se invierte también en las animaciones alternativas.

animation-fill-mode

La última propiedad que vamos a estudiar es animación-fill-mode. Permite especificar cómo el elemento animado aparece al final de una animación o durante una animation-delay. Los valores posibles de animation-fill-mode son:

Para experimentar con algunos de estos efectos, he creado otro ejemplo incluye una animación que mueve el sol girando, y un retardo de animación. Luego he creado cuatro versiones, cada una de las cuales tiene un valor diferente de animation-fill-mode:

Notación rápida para animación

Hay que escribir un montón de código para las animaciones CSS, puesto que hay que escribir varios bloques de fotogramas clave y propiedades múltiples, incluyendo todos los prefijos diferentes. Afortunadamente, se pueden usar abreviaturas para reducir seriamente la cantidad de código necesario.

Las siguientes propiedades:

animation-name: spin;
animation-duration: 3s;
animation-timing-function: linear;
animation-delay: 3s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-fill-mode: both;

pueden ser sustituidas por esta línea:

animation: spin 3s linear 3s infinite alternate both;

La especificación de hecho no es muy específica al definir el orden exacto de los valores de las propiedades en la notación rápida, pero lo mejor es seguir con el orden que se indica aquí arriba para evitar posibles errores del navegador. Varias fuentes indican que este orden cumple con las idiosincrasias de los diferentes navegadores actuales.

Debe incluirse animation-name y animation-duration para que la animación haga algo. Si no se especifican explícitamente los otros valores, se aplicarán los valores predeterminados:

animation-timing-function: ease;
animation-delay: 0s;
animation-iteration-count: 1;
animation-direction: normal;
animation-fill-mode: none;

Pueden aplicar animaciones múltiples en una sola regla incluyéndolas en la misma propiedad, separadas por comas. Esto funciona tanto para la escritura corriente como para la notación rápida. He aquí un ejemplo:

animation: spin 3s, movement 5s;

animation-name: spin, movement;
animation-duration: 3s, 5s;

Si usted está utilizando las propiedades no abreviadas con diferente número de valores, es necesario especificar todos los nombres de animación que deben aplicarse. A partir de ahí, si alguna de las otras propiedades tiene menos valores que el número de animaciones especificado, se alternan para rellenar los huecos. Por ejemplo:

animation-name: spin, movement, glow;
animation-duration: 3s, 5s;
animation-delay: 2s;

La animación de giro tendrá una duración de 3 segundos, y la animación de movimiento tendrá una duración de 5 segundos. La animación glow tendrá un retraso de 3 segundos, ya que los valores de duración se han agotado, por lo que empieza desde el principio otra vez. Todas las animaciones tendrá un retraso de 2 segundos.

Un ejemplo más trabajado

Para terminar el artículo, he creado un ejemplo un poco más interesante con algunas animaciones más trabajadas: echa un vistazo a mi ejemplo de salida de sol. Si analizas el código verás una serie de animaciones que trabajan juntas para producir el efecto final.

Un paisaje de amanecer, creado usando sólo CSS

Resumen

Eso concluye nuestro tour básico de las animaciones CSS: haznos saber tu opinión, y diviértete.

Logo Creative Commons
Los contenidos recogidos en este artículo están sujetos a una licencia Creative Commons
Reconocimiento, No comercial - Compartir bajo la misma licencia 3.0 No adaptada
.
: Ir al índice :