Animaciones de scroll

Animaciones dirigidas por scroll con líneas de tiempo


Cuando profundizamos en el mundo de las animaciones, existen ciertos tipos de animaciones que requieren sincronizarse con el usuario cuando realiza scroll en una página. Este tipo de animaciones, donde se incluyen efectos como parallax, zoom, movimientos, aparición/desaparición, o en definitiva, animaciones específicas dirigidas por scroll, hasta ahora eran muy complejas de realizar, requerían Javascript y podían ser altamente costosas, dependiendo de como se realizaran.

CSS ha añadido una serie de propiedades relacionadas con ellas que permiten generar este tipo de animaciones de forma muy sencilla. Para ello, primero tenemos que aprender algunos conceptos clave que utilizaremos en este tema.

¿Qué es un Timeline?

Las líneas de tiempo (timelines) aparecen en CSS mediante las animaciones. Como su propio nombre indica, se trata de un concepto para medir el tiempo, que parte desde un punto inicial (el minuto cero, cuando carga inicialmente la página) hasta el momento final (el instante actual en el que nos encontramos).

Hasta el momento, esa era la única línea de tiempo que se utilizaba de forma implícita en las animaciones CSS. Sin embargo, con la irrupción de las animaciones dirigidas por scroll, se incluyen dos tipos de líneas de tiempo adicionales:

  • 🔁 Las líneas de tiempo de scroll: Aquellas que permiten realizar una animación a lo largo de un elemento contenedor, controlando su progreso mediante scroll.

  • 💠 Las líneas de tiempo de vistas: Aquellas que permiten realizar una animación a lo largo de un elemento contenedor, sólo cuando este está a la vista en la región visible, controlando su progreso mediante scroll.

Para gestionar estas nuevas líneas de tiempo, utilizaremos la nueva propiedad animation-timeline, con la que asociaremos una animación a una línea de tiempo.

Los valores posibles que puede tomar la propiedad animation-timeline serían los siguientes:

Propiedad Valor Descripción
animation-timeline auto Usa la línea de tiempo por defecto. Valor por defecto.
animation-timeline none No utiliza ninguna línea de tiempo.
animation-timeline --nombre Usa una línea de tiempo con nombre. Lo veremos más adelante.
animation-timeline scroll() Usa una línea de tiempo de scroll.
animation-timeline view() Usa una línea de tiempo de vista.

En principio, vamos a utilizar sobre todo las funciones scroll() y view(), que permiten crear timelines anónimos. Como se puede ver en la tercera opción, las líneas de tiempo pueden también tener un nombre, como por ejemplo, --my-linetime. Hablaremos de ello más adelante.

Precaución: El soporte de esta característica aún no es completo:

Animación de scroll

Vamos a empezar por crear una animación basada en una línea de tiempo anónima. La forma más sencilla es crear una linea de tiempo anónima mediante la función scroll(), que explicaremos más adelante.

Observa el siguiente ejemplo, en el que aún no tenemos nada relacionado con animaciones de scroll, ya que se lo añadiremos más adelante:

body {
  margin: 0;
  font-size: 6rem;
}

.container {
  background: #9994;
  width: 100%;
  height: 6px;
  position: fixed;
  top: 0;
  left: 0;
}

.bar {
  width: 0;
  height: 100%;
  box-shadow: 0 0 5px darkred;
  background: red;
}
<div class="container">
  <div class="bar"></div>
</div>

<p>Escribe aquí un texto lo suficientemente largo como para tener scroll vertical.</p>

Simplemente hemos creado un texto lo suficientemente grande como para tener scroll vertical, y hemos definido una barra de progreso con colores y tamaños mediante CSS en la parte superior. El ancho de la barra de progreso está definido por defecto al 0%. Con una animación de scroll la aumentaremos, seteando el width desde 0 a 100%.

Si tienes dudas sobre animaciones, echa un vistazo a Animaciones CSS y a la regla @keyframes.

Ahora vamos a añadir las dos últimas líneas en la clase .bar y la regla @keyframes:

body {
  margin: 0;
  font-size: 6rem;
}

.container {
  background: #9994;
  width: 100%;
  height: 6px;
  position: fixed;
  top: 0;
  left: 0;
}

.bar {
  width: 0;
  height: 100%;
  box-shadow: 0 0 5px darkred;
  background: red;

  animation: resize auto linear forwards;
  animation-timeline: scroll(root block);
}

@keyframes resize {
  from { width: 0% } /* Se puede omitir */
  to { width: 100% }
}
<div class="container">
  <div class="bar"></div>
</div>

<p>Escribe aquí un texto lo suficientemente largo como para tener scroll vertical.</p>

Observa que más abajo, asociamos la animación resize a la clase .bar y establecemos la duración de la animación a auto, ya que el tiempo lo determina el scroll realizado por el usuario.

Más abajo, utilizamos la función scroll(root block) en la propiedad animation-timeline. Esto lo explicaremos a continuación, pero lo que hace es utilizar la página como contenedor y el eje block (eje y en nuestro idioma, es decir, en vertical).

Esto hará que al hacer scroll en nuestro documento, se produzca la animación de la barra de progreso, acorde a la cantidad de scroll realizado.

La función scroll()

En la propiedad animation-timeline anterior, hemos utilizado la función scroll(), pero aún no la conocemos. En su primer parámetro, se suele indicar el elemento que vamos a usar como contenedor de scroll, y en el segundo parámetro el eje en el que vamos a desplazarnos.

La sintaxis es la siguiente:

Función scroll() Descripción
scroll() Valores por defecto. Equivalente a scroll(nearest block).
scroll( contenedor eje) Indica el contenedor y la orientación del eje de la línea de tiempo.

Observa que los parámetros a utilizar son el contenedor y el eje de la orientación en la que se desplaza. Si se omiten los parámetros, se tomarán los valores por defecto, que son nearest block. Sin embargo, puedes personalizarlos.

Opciones de scroll()

Los parámetros disponibles para la función scroll() son los siguientes:

Parámetros Valores posibles Descripción
container nearest Utiliza el elemento contenedor padre más cercano. Por defecto.
root Utiliza el documento entero como contenedor.
self Utiliza el elemento actual como contenedor específico.
axis block | x Indica el eje horizontal como eje de progreso ⚠️
inline | y Indica el eje vertical como eje de progreso ⚠️

Recuerda que block e inline son las versiones lógicas de x e y respectivamente, y pueden ser diferentes en otros idiomas. Puedes ver más sobre este tema en Propiedades Lógicas en CSS.

Animación de scroll (sólo visible)

La función view() es muy similar a la función scroll(), pero se utiliza en situaciones donde quieres que el elemento comience a animarse sólo cuando esté a la vista del usuario. Se denominan Animaciones de scroll de vista.

Para entender bien la diferencia entre scroll() y view(), veamos el siguiente ejemplo:

<p>Escribe aquí mucho texto para hacer scroll.</p>

<div class="box"></div>

<p>Escribe aquí mucho texto para hacer scroll.</p>

<div class="box"></div>

<p>Escribe aquí mucho texto para hacer scroll.</p>

<style>
body {
  margin: 0;
  font-size: 5rem;
}

.box {
  width: 196px;
  height: 196px;
  background: indigo;
}
</style>

Tenemos dos párrafos extensos de texto y entre ellos, dos cajas de color que tendrán la animación de scroll. Dicha animación, simplemente hace referencia a una animación CSS que desplazará la caja hacia la derecha y la cambiará de color.

La diferencia radica en utilizar la función scroll() o la función view(), donde ambos utilizan sus valores por defecto:

.box {
  animation: change auto linear forwards;
  animation-timeline: view();
}

@keyframes change {
  0% { background: indigo; translate: 0px 0; }
  50% { background: gold; }
  100% { background: deeppink; translate: 400px 0; }
}

Si utilizamos la función scroll(), comprobaremos que al hacer scroll y aparecer la caja, ya ha comenzado la animación, porque la está realizando desde que empezamos a hacer scroll, aunque no estuviera visible. Sin embargo, con la función view() comprobarás que se inicia cuando aparece y es visible en pantalla.

La función view()

La función view() nos viene muy bien para situaciones en las que necesitamos que las animaciones de scroll se realicen justo cuando aparecen en la región visible del navegador. La sintaxis de la función view() es la siguiente:

Función view() Descripción
view() Valores por defecto. Equivalente a view(block auto).
view( eje ajuste) Indica la orientación del eje y un ajuste opcional del rango de visibilidad.

Observa que los parámetros a utilizar son el eje de la orientación en la que se desplaza y un valor de ajuste. Si se omiten los parámetros, se tomarán los valores por defecto, que son block auto. Sin embargo, también puedes personalizarlos.

Opciones de view()

Los parámetros disponibles para la función view() son los siguientes:

Parámetros Valores posibles Descripción
axis block | x Indica el eje horizontal como eje de progreso ⚠️
inline | y Indica el eje vertical como eje de progreso ⚠️
inset auto Utiliza el valor de la propiedad scroll-padding.
tamaño Ajusta la posición donde se dispara la animación en ambos ejes.
x y Ajusta la posición del eje x y el eje y.

Estas son las funcionalidades básicas de las Animaciones de scroll con CSS. En el siguiente artículo veremos como crear animaciones de scroll con nombre, más específicas y definidas.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev