Skip to content

Animaciones y transiciones

Los efectos de animación y transición permiten mover o cambiar la forma de los elementos de la página. Muchos de estos efectos se basan en funciones de transformación que podemos aplicar sobre los elementos. Analizaremos con detalle estos aspectos a continuación.

1. Transformaciones

La propiedad transform nos permite realizar una transformación sobre un elemento. Esta transformación puede ser de varios tipos, dependiendo de la función que apliquemos. Puedes descargar este ejemplo para comprobar el funcionamiento de cada transformación, e incluso modificarlas para ver su comportamiento.

Importante

Es importante que NO haya separación entre el nombre de la función que usemos de transformación (desplazamientos, rotaciones, etc) y los paréntesis que la acompañan.

1.1. Desplazamientos

Comenzaremos con los desplazamientos, con la función translate. Este desplazamiento sólo puede hacerse en relación a la posición actual del elemento. Podemos utilizar dos parámetros: el desplazamiento en X (desde el extremo izquierdo del elemento) y en Y (desde el extremo superior). Ambos admiten valores negativos (para moverse hacia la izquierda y hacia arriba, respectivamente). Por ejemplo, la siguiente regla desplaza una caja 100 píxeles a la derecha y 20 píxeles hacia abajo:

div 
{ 
    transform: translate(100px, 20px); 
}

Si sólo queremos mover en una dirección, tenemos las funciones translateX y translateY, a las que sólo debemos indicarles el movimiento horizontal y vertical, respectivamente. Adicionalmente también tenemos un desplazamiento 3D en el eje Z, con translateZ y con translate3d(x, y, z).

Nota

Podemos utilizar distintos tipos de unidades, en general. En el ejemplo anterior han sido píxeles, pero también podrían ser valores porcentuales, u otras unidades absolutas o relativas. En el caso de valores porcentuales, se toma como base el tamaño del propio elemento.

1.2. Rotaciones

Otra operación de transformación habitual es la rotación alrededor del punto de origen del elemento (por defecto, su centro). Indicamos el ángulo de rotación en grados (grados positivos rotan hacia la derecha, en el sentido horario).

div 
{ 
    transform: rotate(45deg); 
}

De forma análoga a las transformaciones anteriores, también disponemos de rotateY y rotateZ para rotar en torno a los otros dos ejes del espacio 3D, y rotate3d para indicar los 3 ángulos de rotación juntos. Además, en versiones recientes de navegadores también se incluye la propiedad rotate (en lugar de transform) para aplicar esta transformación directamente. Aquí vemos algunos ejemplos:

div 
{
    rotate: 60deg; /* Equivale a transform: rotateZ(60deg); */
    rotate: x 30deg; /* Equivale a transform: rotateX(30deg); */
    rotate: 0 0 1 60deg; /* Equivale a transform: rotateZ(60deg); */
    rotate: 0 1 1 10deg; /* Equivale a transform: rotateY(10deg) rotateZ(10deg); */
}

1.3. Escalados

Podemos también hacer escalados (cambios de tamaño), con la función scale. Le indicamos con dos parámetros el escalado en X e Y (siendo 1 el tamaño real, 0.5 la mitad del tamaño real, 2 el doble del tamaño real, etc.). Si sólo indicamos un valor, se empleará tanto para el escalado en X como para el escalado en Y. Por ejemplo, este estilo escala las imágenes a la mitad de su tamaño en pantalla:

img 
{ 
    transform: scale(0.5, 0.5); 
}

Al igual que en el caso anterior, también tenemos las funciones scaleX y scaleY o scaleZ para escalar sólo en una dimensión, o scale3d para indicar el escalado en las 3 dimensiones. Y de forma análoga a la rotación, disponemos de la propiedad scale compatible con navegadores recientes. Podemos indicar una unidad de escalado para todas las dimensiones o unidades distintas para cada eje.

img
{
    scale: 1.5;  /* Para X, Y y Z */
    scale: 1.25 2; /* Escalado en X e Y */
    scale: 1 1.5 1; /* Eje Y escalado 1.5 */
}

1.4. Torsiones o deformaciones

Finalmente, otro tipo de transformación que podemos aplicar es la deformación a lo largo de los ejes X o Y, con la función skew y derivadas (skewX y skewY, en este caso no existe transformación tridimensional). La inclinación o torsión con respecto a cada eje se indica en grados. Con esto se consigue un elemento inclinado, como con perspectiva.

div 
{ 
    transform: skew(20deg, 5deg); 
}

1.5. Perspectivas

El efecto visual de estas transformaciones dependen del punto en que se halla el observador, lo que se conoce como perspectiva. Este punto de vista también puede establcerse desde CSS, bien mediante la propiedad perspective en un elemento contenedor, o con la función perspective() a la hora de aplicar una transformación determinada.

Se indica como valor la distancia (habitualmente en píxeles) en la que se halla el observador. Valores pequeños harán que el observador esté cerca y la transformación se vea más acentuada. Valores lejanos harán que se aleje el observador y la transformación sea menos perceptible.

#contenedor
{
    /* El observador está a 600px para las transformaciones sobre objetos
       dentro de este contenedor */
    perspective: 600px;
}

#caja1
{
    transform: perspective(600px) rotateX(45deg);
}

1.6. Otras consideraciones

Hemos visto cómo aplicar estas transformaciones por separado. Si queremos aplicar más de una transformación, se ponen una tras otra separadas por espacios:

div 
{ 
    transform: translateX(50px) scale(1.5, 0.25); 
}

En el caso de transformaciones 3D, hay que tener en cuenta que algunos elementos HTML contenidos en otros por defecto tienen su propiedad transform-style en flat, lo que hace que se comporten como objetos 3D. Para que les afecten estas transformaciones tridimensionales debemos asignarle a esta propiedad un valor de preserve-3d.

Por otra parte, la propiedad transform-origin podemos cambiar el punto origen del elemento en una transformación. Podemos especificar el origen en X (left, center, right, porcentaje...), en Y (top, center, bottom, porcentaje...) y en Z (distancia respecto a la base del eje). Además, podemos asignar el valor initial (punto origen por defecto).

div 
{
    transform: rotate(45deg);
    transform-origin: 20% 40%;
}

Ejercicio 1

Toma el ejemplo de transformaciones anterior y aplica los siguientes cambios:

  • Cambia la rotación por una rotación en Y de 45 grados
  • En la caja que se escala, usa la propiedad scale para el escalado, y haz que sea de la mitad en Y y del doble en X.
  • En la caja que tiene una transformación múltiple, establece una perspectiva de 1000px, haz que la rotación sea en X, y añade una translación en Z de 200px.

2. Transiciones

Una transición es un efecto por el que un elemento pasa de un estado o posición inicial a otro, pero no de forma inmediata (como sucede en las transformaciones) sino paulatinamente a lo largo de unos segundos. Por ejemplo, podemos hacer cambios graduales de color, o de posición de un elemento. Para ello, utilizaremos la propiedad transition, a la que le daremos los siguientes valores (separados cada uno por espacios):

  • La propiedad CSS del elemento sobre la que se debe actuar en la transición (por ejemplo: color, width, height, background-color...).
  • La duración de la transición, en segundos (s) o milisegundos (ms).
  • La función de transición (opcional), que puede valer linear (valor por defecto, toda la transición tiene el mismo ritmo), ease (empieza lenta, luego va rápida y termina lenta), ease-in (comienzo lento), ease-out (final lento), etc.
  • Un retraso (opcional) al inicio de la transición, es decir, un tiempo de espera en segundos o milisegundos, antes de empezar.

Si queremos aplicar una transición sobre más de una propiedad, se pone una coma y se repiten estos valores para la siguiente propiedad CSS. Por ejemplo, el siguiente CSS cambia la posición (X) y el color de una caja cuando pasamos el ratón por encima, en una animación de 2 segundos para la posición y 1 segundo para el color, con final lento.

#caja1 
{
    position:relative;
    left: 0px;
    background-color: red;
    transition: background-color 1s ease-out, left 2s ease-out; 
}

#caja1:hover 
{
    background-color: blue;
    left: 100px;
}

Necesitamos definir dos reglas: una con las condiciones iniciales del elemento, y otra con las condiciones que cambien al pasar el ratón por encima (:hover). En las condiciones iniciales, indicamos la(s) transición(es) que queremos, que serán las que cambien hasta las indicadas en la regla :hover, y también indicamos los valores iniciales que tendrán las propiedades que queremos cambiar (posiciones iniciales, colores iniciales...). En la regla :hover simplemente indicamos los valores finales que queramos que tengan las propiedades a cambiar (en el caso anterior, el incremento en X o left y el color de fondo final). En el caso de querer cambiar la posición (left o top), es importante definir el tipo de posicionamiento del objeto (relativo, en el caso anterior).

Notar que obtendríamos el mismo efecto aplicando anidamiento o nesting CSS:

#caja1 
{
    position:relative;
    left: 0px;
    background-color: red;
    transition: background-color 1s ease-out, left 2s ease-out; 

    &:hover 
    {
        background-color: blue;
        left: 100px;
    }
}

También podríamos hacer que las transiciones empiecen al pasar el ratón por encima de otro elemento que contenga al actual, o que esté conectado con él de alguna manera. Por ejemplo, si queremos aplicarlas al entrar con el ratón en cualquier lugar de la página, en lugar de usar el selector #caja1:hover anterior, usaríamos este (también admitiría variante con nesting haciendo html:hover & dentro del item #caja1):

html:hover #caja1 
{
    background-color: blue;
    left: 100px;
}

Ejercicio 2

Crea una página llamada transiciones.html y añádele tres cajas identificadas como caja1, caja2 y caja3. Define para ellas estos estilos:

  • La primera caja (caja1) debe tener una anchura y altura de 200px. Bordes redondeados de 10px de radio y degradado de blanco a naranja, de izquierda a derecha.
  • La segunda caja (caja2) debe tener una anchura de 200px y altura de 400px respectivamente. Debe tener bordes redondeados con 5px de radio, y color rojo claro de fondo.
  • La tercera caja (caja3) debe tener anchura de 300px, y altura de 100px. Debe tener un borde redondeado de color gris de 5px de grosor, y sombra de 10px por la derecha y por abajo, de color negro, sin propagación.
  • Todas las cajas deben tener 10px de margen a cada lado, y posicionarse unas junto a otras (con float o usando grid)

Al final, debe quedarte algo así:

  • Añade una transición a la caja 2 para que, al pasar el ratón por encima, cambie su color del rojo claro al azul claro, en 2 segundos.
  • Añade otra transición a la caja 3 para que, al pasar el ratón por encima, se desplace 20 píxeles hacia abajo, en 1 segundo.
  • Haz que la caja 1 baje 200 píxeles en cuanto pongamos el ratón dentro de la página.

3. Animaciones

Además de todo esto, CSS3 también permite realizar animaciones sobre los elementos. Las animaciones son más complejas que las transiciones porque en éstas sólo hay un estado inicial y uno final, mientras que en una animación hay muchos estados intermedios.

Haremos uso de la propiedad animation y definiremos keyframes, puntos clave entre la animación donde se producirá un cambio de estado. Esto último lo haremos con la regla @keyframes.

La propiedad animation engloba, igual que transition, todas las propiedades de la animación. Algunas son comunes con las transiciones y otras son específicas de las animaciones:

  • Nombre que le damos a la animación (útil para referenciarla luego en los keyframes)
  • Duración
  • Función de timing (linear, ease-in, etc, como en las transiciones)
  • Retardo en empezar a aplicarse (opcional)
  • Iteraciones o número de veces que queremos que se repita la animación (infinite para animaciones continuas)
  • Dirección de la animación: normal (del primer fotograma al último), reverse (del último al primero), alternate (alterna los dos anteriores en animaciones consecutivas)...
  • Modo de relleno: permite establecer una animación previa y posterior (salvo en el caso de animaciones infinitas). Puede valer none, backwards (se dejan los estilos del fotograma inicial), forwards (se dejan los estilos del fotograma final) o both.
  • Estado de la animación: paused, running. Útil combinada con código JavaScript para activar/desactivar la animación.

Aquí vemos un ejemplo de un círculo que se mueve de izquierda a derecha cambiando de color cada cuarto de recorrido completado. Al llegar al final se aplica la animación inversa para volver al inicio (alternate), de modo infinito.

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Animación de círculo</title>
    <style>
        .contenedor 
        {
            background-color: black;
            margin: 10px 10%;
            height: 100px;
        }

        .circulo 
        {
            position: relative;
            left: 0;
            top: 10%;
            width: 80px;
            height: 80px;
            border-radius: 50%;
            background-color: red;
            animation: moverYCambiar 4s linear infinite alternate;
        }

        @keyframes moverYCambiar 
        {
            0% { left: 0%; background-color: red; }
            25% { left: 25%; background-color: orange; }
            50% { left: 50%; background-color: yellow; }
            75% { left: 75%; background-color: green; }
            100% { left: calc(100% - 80px); background-color: blue; }
        }
    </style>
</head>
<body>
    <div class="contenedor">
        <div class="circulo"></div>
    </div>
</body>
</html>

3.1. Más sobre la regla @keyframes

Hemos visto en el ejemplo anterior que la regla @keyframes admite el nombre de la animación sobre la que aplicarse y, dentro, podemos indicar una serie de porcentajes o etapas en las que queremos intervenir en la animación para provocar un cambio de estado (en el ejemplo anterior, modificar el color o la posición del elemento). Entre los puntos de control establecidos el navegador aplica un cambio progresivo de esas propiedades desde su valor inicial (color/posición del estado anterior) hasta su valor final.

Alternativamente, si no queremos establecer esos puntos de control intermedios, podemos emplear los términos from y to para indicar de qué estado inicial a qué estado final queremos llegar. Por ejemplo, esta regla nos permitirá cambiar de un color rojo inicial a uno azul final, de forma progresiva (sin especificar colores intermedios):

@keyframes moverYCambiar 
{
    from { left: 0%; background-color: red; }
    to { left: calc(100% - 80px); background-color: blue; }
}

Ejercicio 3

Crea una página llamada animaciones.html y define en ella una animación de una salida y puesta de sol. El contenedor de fondo irá cambiando de colores oscuros hacia anaranjados al amanecer/atardecer, y azul a mediodía. El sol (círculo en medio de la caja) irá subiendo y bajando hasta ocultarse, pasando de tonos naranjas en la salida/puesta a tonos amarillos a mediodía.

4. Prefijos CSS

Algunas de las opciones que hemos visto en estos documentos no son soportadas por ciertos navegadores, o por ciertas versiones de los mismos. Por este motivo, es habitual en las hojas CSS definir distintas variantes para que cada navegador aplique las que le sean compatibles. Esto se consigue añadiendo ciertos prefijos a las propiedades CSS, de modo que el navegador identifica la que le corresponde.

div{
     transform: ;   /* Navegadores que implementan especificación oficial */
     -webkit-transform: ;   /* Versiones antiguas de Chrome (Motor Webkit) */
     -moz-transform: ;   /* Versiones antiguas de Firefox (Motor Gecko) */
     -ms-transform: ;   /* Versiones antiguas de IE/Edge (Motor Trident) */
     -o-transform: ;   /* Versiones antiguas de Opera (Motor Presto) */
}