Skip to content

Animaciones y transiciones CSS

Las animaciones pueden ayudar a cumplir estos dos propósitos:

  • Guía y clarificación: Queremos guiar al usuario a hacer cosas, y queremos que sepa qué puede hacerlas y cuál es el resultado.
  • Estilo y marca: Al igual que su sitio web, puede una paleta de colores o una fuente personalizada, que se vincule a la marca. Se puede hacer lo mismo con las animaciones y transiciones.

Fundamentos

Duración: Duración de la animación o transición. Tenemos que hacer una diferencia con la duración infinita, en este punto no nos interesa si se ejecuta de forma infinita. Nos intersa el tiempo de la iteración de esa animación. Ejemplo, un spinner, puede estar de forma infinita, pero aqui contamos los segundos que tarda a dar una vuelta.

  • animation-duration: Duración de la animación.
  • animation-itertion-count: Número de veces que se ejecuta la animación. Si es infinito, se pone infinite.

Delay: Es el tiempo que transcurre antes de que comience una animación o una transición. Cuando hace clic en algo que inicie una animación, puede haber un retraso antes de que comience la animación. El retraso solo sucede una vez! no se repite.

  • animation-delay: Tiempo de espera antes de que comience la animación. Si se establece en 0s, la animación comienza inmediatamente. Si se establece en 2s, la animación comienza 2 segundos después de que se cargue la página.

Timing function/aceleración de la animación: Cómo se acelera y desacelera con el tiempo. Entonces, si una animación dura un segundo y tiene una aceleración lineal, que mostraremos en un minuto, entonces tendrá la misma velocidad constante de principio a fin. Sin embargo, las animaciones podemos hacer que no sean lineales, con cubic-bezier(x1,y1,x2,y2).

css
animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);
animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1);

Se recomiend que los valores y1 = 0 y y2 = 1. cubic-bezier(0.5, 0, 0.5, 1) La razón es porque se vuelve mucho menos confuso averiguar los otros dos números. Porque cuando haces eso, los otros dos números simplemente se convierten en algo que puedes ajustar, y podrías describir la mayoría de las curvas así. Y también porque se parece más al mundo real. Cuando algo comienza a moverse, comenzará a una velocidad de cero.

Variables: Las animaciones y transiciones CSS pueden usar variables CSS. Esto significa que podemos usar valores dinámicos en nuestras animaciones y transiciones. Por convención, las variables CSS se nombran en root.

html
<div class="box"></div>
<div class="box"></div>
css
:root {
  --border-size: 2px; /* -- indica que es una variable custom */
  --height-size: 500px;
}

.box {
  width: 100px;
  height: var(--height-size);
  background-color: var(--custom-red);
  border: var(--border-size) solid black;
}
:root {
  --border-size: 2px; /* -- indica que es una variable custom */
  --height-size: 500px;
}

.box {
  width: 100px;
  height: var(--height-size);
  background-color: var(--custom-red);
  border: var(--border-size) solid black;
}

También se pueden añadir variables css con js. O asignar un valor a una clase en concreto

js
const box = document.querySelector(".box");
box.style.setProperty("--custom-red", "red");
box.style.setProperty("--height-size", "100px");
const box = document.querySelector(".box");
box.style.setProperty("--custom-red", "red");
box.style.setProperty("--height-size", "100px");

link al ejemplo

¿Qué animar?

Al poner animaciones podemos afectar al rendimiento de la página. Por lo que hay que tener cuidado con lo que animamos. Por ejemplo, no animar el tamaño de un elemento, porque eso puede afectar al layout de la página, y suponen un montón de renderizaciones y cambios de posición. Lo que si podemos animar es el color, la opacidad, etc.

Estos afectos de la performance los tiene en cuenta google, por lo que afecta al SEO de tu página

Transiciones

Las transiciones son animaciones que se ejecutan cuando un estado cambia. Por ejemplo, cuando un elemento cambia de color, o cuando se hace un hover sobre un elemento.

css
.box {
  background-color: red;
  transition: background-color 1s;
}

.box:hover {
  background-color: blue;
}
.box {
  background-color: red;
  transition: background-color 1s;
}

.box:hover {
  background-color: blue;
}

transition-property: Propiedad que queremos animar. Si no se especifica, se anima todas las propiedades. Si se especifica, se anima solo la propiedad indicada.

En este ejemplo, la animación se ejecuta unicamente en el background-color, y el cambio de la scale, sera instantaneo.

html
<div class="box"></div>
<div class="box"></div>
css
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  transition-property: background-color;
  transition-duration: 1s;
}

.box:hover {
  background-color: blue;
  transform: scale(2);
}
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  transition-property: background-color;
  transition-duration: 1s;
}

.box:hover {
  background-color: blue;
  transform: scale(2);
}

link al ejemplo

hover

También acepta múltiples propiedades separadas por comas, entonces le podemos dar a cada transición una duración diferente.

css
transition-property: background-color, transform;
transition-duration: 1s, 2s;
transition-property: background-color, transform;
transition-duration: 1s, 2s;

Keyframes

Las keyframes son un conjunto de reglas que definen el estado de un elemento en un momento determinado. Por ejemplo, en el 0% el elemento tiene un color rojo, en el 50% el color es azul, y en el 100% el color es verde.

css
@keyframes my-animation {
  0% {
    background-color: red;
  }
  50% {
    background-color: blue;
  }
  100% {
    background-color: green;
  }
}
@keyframes my-animation {
  0% {
    background-color: red;
  }
  50% {
    background-color: blue;
  }
  100% {
    background-color: green;
  }
}

Se tienen que hacer las animaciones lo más naturales posibles, por ejemplo, en el caso de la posición seguramente sea buena idea que vuelva a su posición inicial. También no solo podemos utilizar valores de tanto por ciento, sino también from y to.

html
<div class="circle"></div>
<div class="circle"></div>
css
.circle {
  width: 50px;
  height: 50px;
  background-color: red;
  border-radius: 50%;
  animation-name: move-like-a-square, red-to-blue;
  animation-duration: 2s;
  animation-iteration-count: infinite;
}

@keyframes move-like-a-square {
  from,
  to {
    /* 0%, 100% */
    transform: translate(0, 0);
  }

  25% {
    transform: translate(50px, 0);
  }

  50% {
    transform: translate(50px, 50px);
  }

  75% {
    transform: translate(0, 50px);
  }
}

@keyframes red-to-blue {
  from {
    background-color: red;
    /* we can NOT add a tranform, conlfict with the other animation */
  }

  to {
    background-color: blue;
  }
}
.circle {
  width: 50px;
  height: 50px;
  background-color: red;
  border-radius: 50%;
  animation-name: move-like-a-square, red-to-blue;
  animation-duration: 2s;
  animation-iteration-count: infinite;
}

@keyframes move-like-a-square {
  from,
  to {
    /* 0%, 100% */
    transform: translate(0, 0);
  }

  25% {
    transform: translate(50px, 0);
  }

  50% {
    transform: translate(50px, 50px);
  }

  75% {
    transform: translate(0, 50px);
  }
}

@keyframes red-to-blue {
  from {
    background-color: red;
    /* we can NOT add a tranform, conlfict with the other animation */
  }

  to {
    background-color: blue;
  }
}

link al ejemplo

Choreography

Siempre hemos tratado a las animaciones de manera individual, pero podemos hacer que se ejecuten en un orden determinado. Asi que coreography es para coordinar diferentes animaciones entre si, para convertirla en una sola animación.

Se puede hacer de manera simple, con la propiedad animation-delay que nos permite dar un retraso a la animación.

html
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
css
.circle {
  width: 50px;
  height: 50px;
  background-color: red;
  border-radius: 50%;
  animation: red-to-blue 0.5s both;
}

.circle:nth-child(2) {
  animation-delay: 1s;
}

.circle:nth-child(3) {
  animation-delay: 2s;
}

@keyframes red-to-blue {
  from {
    background-color: red;
  }

  to {
    background-color: blue;
  }
}
.circle {
  width: 50px;
  height: 50px;
  background-color: red;
  border-radius: 50%;
  animation: red-to-blue 0.5s both;
}

.circle:nth-child(2) {
  animation-delay: 1s;
}

.circle:nth-child(3) {
  animation-delay: 2s;
}

@keyframes red-to-blue {
  from {
    background-color: red;
  }

  to {
    background-color: blue;
  }
}

Link al ejemplo

Complex Choreography

Para poder de manera más escalable, se pueden utilizar variables CSS para poder controlar el orden de las animaciones. Y utilizar stagger animations, para evitar sobrepongan las animaciones, de igual manera, añadir una variable a cada elemento para poder controlar el orden de las animaciones.

html
<div class="circle" style="--i: 0"></div>
<div class="circle" style="--i: 1"></div>
<div class="circle" style="--i: 2"></div>
<div class="circle" style="--i: 0"></div>
<div class="circle" style="--i: 1"></div>
<div class="circle" style="--i: 2"></div>
css
.circle {
  --duration: 1s;
  --stagger: 0.5s;
  --interval: calc(var(--duration) - var(--stagger));

  width: 50px;
  height: 50px;
  background-color: red;
  border-radius: 50%;
  animation: red-to-blue var(--duration) calc(var(--interval) * var(--i)) both; /* calc(var(--interval) * var(--i)) it's the delay */
}

@keyframes red-to-blue {
  from {
    background-color: red;
  }

  to {
    background-color: blue;
  }
}
.circle {
  --duration: 1s;
  --stagger: 0.5s;
  --interval: calc(var(--duration) - var(--stagger));

  width: 50px;
  height: 50px;
  background-color: red;
  border-radius: 50%;
  animation: red-to-blue var(--duration) calc(var(--interval) * var(--i)) both; /* calc(var(--interval) * var(--i)) it's the delay */
}

@keyframes red-to-blue {
  from {
    background-color: red;
  }

  to {
    background-color: blue;
  }
}

link al ejemplo

Estados

Al momento de hacer animaciones, es importante tener en cuenta los estados de los elementos.

Por ejemplo en un boton, puede tener hover, focus, active, disabled. Y algunos de ellos pueden ser simultaneos, por ejemplo, un boton puede tener hover y active al mismo tiempo.

Para la gestion de un estado, nos puede servir crear atributos personalizados.

html
<button data-state="loading">Click</button>
<button data-state="loading">Click</button>

Usualmente modificamos el estado de un elemento con javascript, por ejemplo, cuando se hace click en el boton, se cambia el estado a loading.

js
const button = document.querySelector("button");
button.addEventListener("click", () => {
  button.setAttribute("data-state", "success");
});
const button = document.querySelector("button");
button.addEventListener("click", () => {
  button.setAttribute("data-state", "success");
});

Ahora bien, es un poco verboso y podemos hacerlo de una manera más sencilla.

js
const button = document.querySelector("button");
button.addEventListener("click", () => {
  button.dataset.state = "success";
});
const button = document.querySelector("button");
button.addEventListener("click", () => {
  button.dataset.state = "success";
});

A nivel de CSS, podemos utilizar el atributo personalizado para poder aplicar estilos.

css
button[data-state="loading"] {
  background-color: blue;
}
button[data-state="loading"] {
  background-color: blue;
}

Last updated: