Ir al contenido

El medio de los artesanos de la web domingo, 25 de octubre de 2026

MailStudio
Diseño y UX

Animaciones controladas por el scroll en CSS: scroll-timeline y view-timeline sin JavaScript

Las animaciones controladas por el scroll, basadas en animation-timeline, scroll-timeline y view-timeline, ya funcionan de forma nativa en los tres motores principales: Firefox y Safari se sumaron a Chrome en 2026. Sincronizan una animación CSS con la posición de scroll sin un…

Las animaciones controladas por el scroll se apoyan en tres propiedades CSS: animation-timeline, scroll-timeline y view-timeline. Compatibles con Chrome y Edge desde 2023, completaron su recorrido de compatibilidad en 2026 con la llegada de Firefox (versión 159) y Safari (versión 26.0), alcanzando alrededor del 87,8 % de cobertura mundial de navegadores. Ya es posible sincronizar una animación con la posición de scroll sin escuchar un solo evento scroll en JavaScript.

Dos timelines, un mismo principio

Una timeline de scroll sustituye el tiempo por un progreso del 0 % al 100 %. Existen dos variantes. La scroll progress timeline (scroll-timeline) mide el progreso del scroll dentro de un contenedor, de arriba abajo. La view progress timeline (view-timeline) mide, en cambio, el progreso de un elemento concreto a través del viewport visible: 0 % cuando entra, 100 % cuando sale.

Comparación entre scroll-timeline y view-timeline

scroll-timeline 0% en la parte superior del contenedor 100% al final

view-timeline 0% al entrar el elemento en el viewport 100% al salir


Poner en práctica scroll-timeline y view-timeline

Una barra de progreso de lectura

El caso más habitual es la barra de progreso de un artículo, que se va llenando a medida que se desplaza la página.

<div class="progress-track">
  <div class="progress-bar"></div>
</div>
:root {
  timeline-scope: --page-scroll;
}

html {
  scroll-timeline: --page-scroll block;
}

.progress-bar {
  animation: rellenar linear;
  animation-timeline: --page-scroll;
}

@keyframes rellenar {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

Sin gestores de eventos ni cálculos manuales de porcentaje: el motor de renderizado interpola directamente las propiedades animadas en función del progreso del scroll.

Revelar una tarjeta al entrar en el viewport

Para efectos de aparición al hacer scroll (fundido, desplazamiento), view-timeline apunta directamente al elemento que se anima, en lugar de al contenedor que se desplaza.

.tarjeta {
  view-timeline-name: --aparicion-tarjeta;
  view-timeline-axis: block;

  animation: aparecer linear;
  animation-timeline: --aparicion-tarjeta;
  animation-range: entry 10% cover 40%;
}

@keyframes aparecer {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}

animation-range delimita el tramo en el que se reproduce la animación: aquí empieza cuando la tarjeta ha recorrido el 10 % de su entrada en el viewport y termina al 40 % de su recorrido completo, para evitar un efecto que se dispare demasiado pronto o termine demasiado tarde.

Una timeline de scroll no escucha ningún evento: el progreso se calcula directamente en el pipeline de estilos del motor de renderizado, sin pasar por el hilo principal de JavaScript.

Compatibilidad, alternativa y depuración

Compatibilidad real por fin en 2026

NavegadorVersión mínimaLlegada
Chrome115Julio de 2023
Edge115Julio de 2023
Safari26.02026
Firefox1592026

La compatibilidad de Firefox y Safari solo llegó este año: hasta entonces, las tres propiedades quedaban reservadas a efectos estrictamente progresivos, sin animación en los navegadores no compatibles.

Depurar una timeline en las herramientas de desarrollo

Chrome y Edge muestran las timelines de scroll activas directamente en el panel de Animaciones de las herramientas de desarrollo: cada timeline aparece con su progreso actual, visible al desplazar la página mientras el panel permanece abierto. Es la forma más rápida de comprobar que un animation-range empieza y termina en el punto correcto, en lugar de adivinar los valores a base de prueba y error en la hoja de estilos. Firefox ofrece una inspección equivalente desde que llegó la compatibilidad en su versión 159.

Alternativa para navegadores no compatibles

Para audiencias que todavía cuentan con una parte de navegadores antiguos, una consulta de característica evita servir un contenido congelado por un error de estilo en lugar de por la ausencia de animación:

@supports (animation-timeline: works) {
  .tarjeta {
    opacity: 0;
  }
}

Sin esta comprobación, un elemento cuyo estado inicial depende de la animación (aquí, opacidad 0 antes de aparecer) permanecería invisible en un navegador que nunca reproduce la animación.

Accesibilidad, carrusel y rendimiento

Respetar la preferencia de movimiento reducido

Una animación de aparición o de parallax ligada al scroll debe permanecer silenciosa para quienes han activado la reducción de movimiento en su sistema. Desactivarla por completo en ese caso, en lugar de ralentizarla, evita cualquier efecto de superposición con contenido atascado a mitad de animación.
@media (prefers-reduced-motion: reduce) {
  .tarjeta {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

Combinar scroll-snap y view-timeline para un carrusel guiado

Ambos mecanismos se combinan bien: un contenedor con scroll-snap-type impone una parada limpia en cada diapositiva, mientras que una view-timeline aplicada a cada elemento del carrusel controla su escala u opacidad mientras atraviesa la zona central.

.carrusel {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}

.carrusel > * {
  scroll-snap-align: center;
  view-timeline-name: --diapositiva;
  view-timeline-axis: inline;

  animation: reducir-en-bordes linear;
  animation-timeline: --diapositiva;
  animation-range: cover 0% cover 100%;
}

@keyframes reducir-en-bordes {
  0%, 100% { transform: scale(0.85); opacity: 0.5; }
  50%      { transform: scale(1);    opacity: 1;   }
}

El resultado: la diapositiva centrada crece ligeramente y las vecinas se reducen, sin que ningún script recalcule la posición de scroll fotograma a fotograma.

Incidencia en el rendimiento

Estas animaciones se ejecutan en el pipeline de estilos del motor de renderizado en lugar de en un bucle requestAnimationFrame controlado por el hilo principal. En la práctica, un scroll rápido ya no compite con el JavaScript propio de la página por los mismos recursos de CPU, lo que reduce el riesgo de tirones en dispositivos de gama baja. La contrapartida: solo las propiedades que pueden animarse por composición (transform y opacity, sobre todo) se mantienen fluidas sin saltos; animar propiedades que provocan reflujo (como width o top) sigue siendo costoso, haya o no timeline de scroll de por medio.

Casos de uso en producción

Más allá de la barra de progreso, las apariciones de tarjetas y el carrusel anterior, el mismo mecanismo sirve para reducir una cabecera de página al hacer scroll o para un ligero efecto de parallax en una imagen. En todos los casos, la animación permanece declarativa y deja de depender de una biblioteca JavaScript dedicada al scroll, a diferencia de los enfoques que todavía hacen falta para transiciones de página completas, como las que detallamos en nuestro artículo sobre View Transitions.

Este mecanismo complementa bien las técnicas ya disponibles sin JavaScript, desde el posicionamiento de anclaje CSS para menús y tooltips hasta las container queries para componentes adaptativos: la maquetación y la interacción siguen migrando de JavaScript hacia mecanismos declarativos gestionados de forma nativa por el motor de renderizado.

Lo que hay que recordar

Con la llegada de Firefox 159 y Safari 26, las animaciones controladas por el scroll cubren ya la inmensa mayoría del parque de navegadores y pueden pasar de curiosidad experimental a herramienta de producción. Una consulta @supports como alternativa y el respeto de prefers-reduced-motion siguen siendo las dos precauciones que evitan que una mejora visual se convierta en una regresión de accesibilidad.

Este año sustituí una biblioteca JavaScript de parallax por estas tres propiedades en un proyecto para un cliente, con una ganancia clara de fluidez en móvil y una línea de dependencia menos en el bundle. Mi única pega: la documentación sigue repartida entre MDN y las entradas del blog de Chrome, y cada animation-range hay que ajustarlo a base de prueba y error. — Simon Janvier

Para saber más: la referencia de CSS Scroll-driven Animations en MDN.

Compartir LinkedIn Bluesky Hacker News E-mail

Leer también