La propiedad transition de CSS para realizar animaciones es muy cómoda y fácil de usar, pero esa misma sencillez hace que no sean apropiadas si buscamos algunos efectos de animación más complejos. Eso es algo que podemos alcanzar si usamos las animaciones de CSS basadas en línea de tiempo.
Aunque son algo más complicadas de configurar que las transiciones, las animaciones por fotogramas clave tienen varias ventajas que las pueden convertir en el componente obligatorio con el que trabajar si estamos buscando alguna de estas características:
Son independientes del elemento que animan
Esto significa que una misma animación
puede ser usada sobre diferentes elementos sin tener que repetir su declaración. Solamente tenemos
que asociarla a cada uno de ellos.Se pueden lanzar inmeditamente
Esto es, no necesitan un cambio de alguna de las
propiedades CSS para ejecutarse, aunque ganaremos dinamismo si las vinculamos a algún tipo de
cambio, como la pseudo-clase hover.Tienen control de repeticiones
Esto permite tener elementos animados de forma continua
(en bucle) sin tener que recurrir a javascript.Separa fotogramas de propiedades de animación
Esto hace que podamos usar una misma
animación con tiempos y modos de reproducción diferentes en cada uno de los elementos en los que se
use. Para construir la animación de este tipo se usa la directiva @keyframe seguida del nombre que le queremos dar a la animación. Y dentro de ella establecemos los diferentes fotogramas clave de nuestra línea de tiempo, especificando en cada uno de ellos qué propiedades cambian, con sus nuevos valores.
Estos fotogramas clave se expresan en porcentajes sobre el tiempo total de la animación. Es conveniente, pero no necesario, definir los fotogramas clave de inicio y final, que pueden ser expresados como 0% y 100% o usando las palabras clave from y to.
A medida que necesitemos cambiar valores de nuestra animación, añadimos el fotograma clave correspondiente, indicando su momento en la animación de forma porcentual, y estableciendo los nuevos valores para las propiedades deseadas. De este modo, añadiendo fotogramas clave, es como construimos nuestra línea de tiempo.
Así, declarar una animación para que mueva un elemento hacia la izquierda, desplazándose el espacio de su anchura sería algo así:
@keyframes desplaza {
from {
transform: translate(0, 0);
}
to {
transform: translate(100%, 0);
}
}
Y si queremos que a mitad de animación cambie su color de fondo a naranja añadimos un nuevo fotograma clave así:
@keyframes desplaza {
from {
transform: translate(0, 0);
}
50% {
background: orange;
}
to {
transform: translate(100%, 0);
}
}
O así
@keyframes desplaza {
from {
transform: translate(0, 0);
}
to {
transform: translate(100%, 0);
}
50% {
background: orange;
}
}
Como vemos en el ejemplo, el orden en el que se definen los fotogramas no tiene que ser secuencial, podemos poner cualquier punto en cualquier momento. Pero si la animación va a tener cierta complejidad es preferible hacerlo de forma secuencial, de 0 a 100%, para que su edición nos resulte más cómoda.
La animación definida en un @keyframe se vincula al elemento que queramos animar mediante la propiedad CSS animation-name dentro del selector CSS del elemento. Esto hace que las propiedades definidas en esos fotogramas se apliquen sobre el elemento según los intervalos de tiempo de la animación.
De este modo, para añadir la animación del ejemplo anterior a un elemento div que tiene aplicada la clase CSS cuadro, podríamos hacer algo así dentro de esa clase:
.muestra {
width: 50%;
height: 50px;
background: violet;
animation-name: desplaza;
}
Pero esta propiedad únicamente no es suficiente para que la animación funcione. Es necesario definir, por lo menos, una segunda propiedad que establezca el tiempo que va a durar la animación. Es la propiedad animation-duration. Con estas dos definidas ya tendríamos una animación que se ejecuta de forma inmediata cuando sea leído y aplicado el CSS del elemento. Quedando algo así:
.muestra {
width: 50%;
height: 50px;
background: violet;
animation-name: desplaza;
animation-duration: 3s;
}
El resultado de la animación anterior sería este:
Para entender por completo este tipo de animaciones hay que saber que @keyframes solamente define el aspeto de los fotogramas clave. Es decir, qué cosas cambian en cada momento de la línea de tiempo, del elemento que vamos a animar. Pero no tiene propiedades que se refieran a la propia animación, como por ejemplo, la aceleración o el tiempo de retraso. Estas propiedades pertenecen al propio elemento que animamos, y se definen como las propiedades animation-name y animation-duration. Este es el listado completo de las propiedades disponibles para cualquier animación:
animation-name
Especifica el nombre de la regla @keyframes que describe los
fotogramas de la animación.animation-duration
Indica la cantidad de tiempo que la animación consume en completar
su ciclo (duración). animation-delay
Tiempo de retardo entre el momento en que el elemento se carga y el
comienzo de la secuencia de la animación.animation-iteration-count
El número de veces que se repite. Podemos indicar
infinite para repetir la animación indefinidamente.animation-timing-function
Indica el ritmo de la animación, es decir, como se muestran
los fotogramas de la animación, estableciendo curvas de aceleración.animation-direction
Indica si la animación debe retroceder hasta el fotograma de
inicio al finalizar la secuencia o si debe comenzar desde el principio al llegar al final.
animation-play-state
Permite pausar y reanudar la secuencia de la animación.
animation-fill-mode
Especifica qué valores tendrán las propiedades a animar cuando no
se ejecuta la animación, es decir, antes de empezar y después de terminar. Y pueden ser los del
primer fotograma, los del último, o ambos. Como con muchas otras propiedades, CSS tiene una versión shorthand que resume las siete
subpropiedades en la propiedad principal animation. Esta sería su notación:
animation: name duration timing-function delay iteration-count direction fill-mode;
. Y este es
un ejemplo de la propiedad en modo abreviado:
animation: desplaza 10s ease-in-out 0s infinite alternate both;
Vamos a usar la siguiente animación para aplicarla a los 3 elementos de la derecha, usando la clase del ejemplo. Además, para cada elemento definiremos distintas propiedades de animación para ver su resultado:
@keyframes grafico {
from {
height: 5px;
}
70% {
background-color: darkgoldenrod;
}
to {
height: 100%;
box-shadow: 2px 2px 1px black;
background-color: gold;
}
}
.barra {
width: 150px;
height: 5px;
background: orange;
position: absolute;
bottom: 0;
animation: grafico 1s 3;
animation-play-state: paused;
}
Animación básica que muestra el estado del último fotograma al terminar
#barra1 {
animation-fill-mode: forwards;
}
Animación de ida y vuelta.
#barra2 {
animation-fill-mode: forwards;
animation-direction: alternate;
}
Animación con retraso en el inicio y ciclo infinito
#barra3 {
animation-delay: 0.5s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
La página de MDN sobre @keyframes tiene documentación detallada sobre este componente. Son especialmente interesantes los ejemplos sobre cómo aplicar varias animaciones a un mismo elemento. También detalla los eventos de la animación disponibles para su manejo desde JavaScript. Aunque de momento no está traducida al castellano.
Esta es la ruta: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations
Y este es un ejemplo de aplicación interesante de esta propiedad, combinada con el pseudo-elemento ::target
Aquí: http://w3.unpocodetodo.info/css3/ejemplos/target-keyframes.html#articulo3