Blanche
Blanche Agency

Blanche · Studio

© 2026

Adiós al JavaScript: Creando Experiencias de Scroll Cinematográficas con CSS Puro en 2025
Volver al blog
Desarrollo WebOptimización del RendimientoDiseño de Movimiento16 de abril de 2026·10 min de lectura

Adiós al JavaScript: Creando Experiencias de Scroll Cinematográficas con CSS Puro en 2025

La especificación CSS Scroll-Driven Animations ha dejado en silencio a las pesadas librerías JavaScript de scroll con aspecto de exceso — así es como puedes lanzar encabezados parallax, revelaciones escalonadas e indicadores de progreso sticky sin ninguna sobrecarga de JS.

El Renacimiento de las Animaciones de Scroll que Nadie Vio Venir

Durante la mayor parte de la última década, si querías animaciones de scroll suaves como la seda en un sitio web en producción, recurrías a JavaScript. ScrollTrigger de GSAP se convirtió en el estándar de facto. Locomotive Scroll encontró su camino en prácticamente el boilerplate de cada agencia creativa. El Intersection Observer parecía toda una revelación. Aceptamos que la magia del scroll implicaba enviar kilobytes de lógica de orquestación, luchar contra el jank en dispositivos Android de gama media y rezar para que tu librería de scroll no entrase en conflicto con el lazy-loader de tu CMS.

Luego, algo cambió silenciosamente.

Chrome 115 lanzó soporte completo para la especificación CSS Scroll-Driven Animations a mediados de 2023, y para 2025, el panorama de compatibilidad con navegadores ha cambiado drásticamente. Lo que comenzó como una propuesta de especificación que parecía demasiado buena para ser verdad — animaciones de scroll nativas, compuestas y sin JavaScript — es ahora una herramienta legítima para producción. Esto no es una historia de polyfills. No es un "espera a una adopción más amplia". Es lánzalo ahora, mejora progresivamente, duerme tranquilo.

Vamos a profundizar en cómo funciona exactamente, dónde gana y — de manera crítica — dónde aún deberías recurrir a JS.


Entendiendo la Especificación CSS Scroll-Driven Animations en Palabras Simples

La especificación introduce dos primitivas fundamentales que funcionan en conjunto con la Web Animations API existente y la propiedad CSS animation: animation timelines y animation ranges.

La Propiedad animation-timeline

Tradicionalmente, las animaciones CSS están controladas por el tiempo — una duración en segundos o milisegundos. Las Scroll-Driven Animations reemplazan ese reloj con una posición de scroll. Defines una línea de tiempo basada en un contenedor de scroll, y el navegador mapea el progreso del scroll (de 0% a 100%) directamente al progreso de la animación.

Existen dos tipos de timeline:

  • scroll() — rastrea el progreso del scroll de un contenedor desplazable (por defecto el ancestro desplazable más cercano o el viewport)
  • view() — rastrea cuánto ha recorrido un elemento a través del viewport visible
.hero-parallax {
  animation: parallax-drift linear;
  animation-timeline: scroll(root block);
  animation-duration: auto; /* Requerido — deshabilita la duración basada en tiempo */
}

@keyframes parallax-drift {
  from { transform: translateY(0); }
  to   { transform: translateY(-120px); }
}

Ese animation-duration: auto es el apretón de manos secreto. Le dice al navegador: no uses el tiempo, usa la posición de scroll como controlador.

El Timeline view() y animation-range

La función view() es donde las cosas se ponen genuinamente emocionantes para las animaciones de revelación. Se activa de forma relativa a cuando un elemento entra y sale del viewport, no según la posición de scroll de la página.

.card {
  animation: fade-up both linear;
  animation-timeline: view();
  animation-range: entry 0% entry 40%;
}

@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(40px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

animation-range te permite apuntar a fases específicas: entry, exit, contain y cover. Esto es el equivalente a los marcadores start y end de ScrollTrigger — sin necesidad de JavaScript.

Timelines con Nombre mediante scroll-timeline-name

Para coordinar animaciones entre elementos (imagina una barra lateral sticky sincronizada con una columna de contenido desplazable), puedes nombrar un timeline en un elemento padre y consumirlo desde un hijo:

.scroll-container {
  overflow-y: scroll;
  scroll-timeline-name: --main-scroll;
  scroll-timeline-axis: block;
}

.progress-bar {
  animation: grow-bar linear;
  animation-timeline: --main-scroll;
  animation-duration: auto;
}

Esta herencia de timeline de padre a hijo es la pieza arquitectónica que hace posible la coreografía compleja de múltiples elementos sin una sola línea de JS.


Análisis de Rendimiento en Profundidad: CSS Nativo vs. Librerías de Scroll en JS

Esta es la cruda verdad de por qué esto importa más allá de la elegancia sintáctica: las animaciones de scroll en JavaScript están arquitectónicamente luchando contra el navegador, mientras que las animaciones de scroll en CSS trabajan con él.

Cuando GSAP ScrollTrigger (o cualquier librería de scroll) se activa:

  1. Escucha eventos de scroll en el hilo principal
  2. Calcula posiciones de elementos, potencialmente disparando layout/reflow
  3. Aplica mutaciones de estilo — que el navegador luego tiene que componer

Incluso con las optimizaciones de requestAnimationFrame y will-change, sigues tocando el hilo principal en cada tick de scroll. En una pantalla de 120Hz, son 120 oportunidades por segundo de introducir jank.

Las CSS Scroll-Driven Animations se ejecutan enteramente en el hilo del compositor. El motor de renderizado del navegador maneja los cálculos de animación de forma aislada respecto a la ejecución de JavaScript, el layout y la pintura. Los eventos de scroll nunca llegan a tu runtime de JS.

En la práctica, esto significa:

  • Sin jank causado por tareas JS largas que bloqueen las actualizaciones vinculadas al scroll
  • Sin sobrecarga de listeners de scroll — especialmente significativo en móviles donde la batería y el throttling térmico afectan el rendimiento de JS
  • Coste cero en el bundleanimation-timeline: scroll() no envía ningún byte
  • Pausa y reanudación automática cuando la pestaña pasa a segundo plano, sin código de ciclo de vida personalizado

Los propios benchmarks del equipo de Chromium muestran que las animaciones CSS scroll-driven mantienen 60fps bajo condiciones que reducían los equivalentes impulsados por GSAP a 40-45fps en dispositivos de gama media. Para una agencia creativa que lanza campañas a audiencias amplias de consumidores, esa diferencia es real.

GSAP sigue siendo excepcional — pero para los efectos vinculados al scroll, ahora estás pagando un coste de rendimiento que no tienes que asumir.


Cinco Efectos de Scroll Listos para Producción que Puedes Lanzar Esta Semana

1. Encabezado Hero con Parallax

El clásico. El fondo se mueve a una velocidad menor que el scroll de la página:

.hero {
  background-image: url('/hero.jpg');
  background-attachment: fixed; /* Hack antiguo — no lo uses */
  animation: hero-parallax linear;
  animation-timeline: scroll(root);
  animation-duration: auto;
}

@keyframes hero-parallax {
  to { background-position: center 40%; }
}

2. Indicador de Progreso de Lectura

Una barra de progreso que se llena mientras el usuario lee — sin JS:

.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  background: #6c63ff;
  transform-origin: left;
  animation: progress-grow linear;
  animation-timeline: scroll(root block);
  animation-duration: auto;
}

@keyframes progress-grow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

3. Cuadrícula de Tarjetas con Revelación Escalonada

Asigna a cada tarjeta un retraso usando animation-delay junto con los timelines de view():

.card-grid .card {
  animation: card-reveal both ease-out;
  animation-timeline: view();
  animation-range: entry 10% entry 50%;
}

.card:nth-child(2) { animation-delay: calc(1 * 60ms); }
.card:nth-child(3) { animation-delay: calc(2 * 60ms); }
/* Continúa el patrón o usa @layer con un bucle en tu herramienta de build */

@keyframes card-reveal {
  from { opacity: 0; transform: scale(0.94) translateY(20px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

4. Etiqueta de Sección Sticky con Transiciones de Fundido

Un título de sección que aparece con fundido al entrar y desaparece al salir:

.section-label {
  position: sticky;
  top: 2rem;
  animation: label-lifecycle linear both;
  animation-timeline: view();
  animation-range: entry 0% exit 100%;
}

@keyframes label-lifecycle {
  0%, 100% { opacity: 0; }
  15%, 85% { opacity: 1; }
}

5. Marquesina de Texto Horizontal Sincronizada con el Scroll

Texto que se mueve lateralmente mientras haces scroll hacia abajo — un efecto característico de las agencias creativas:

.marquee-text {
  white-space: nowrap;
  animation: marquee-slide linear;
  animation-timeline: scroll(root);
  animation-duration: auto;
}

@keyframes marquee-slide {
  from { transform: translateX(0); }
  to   { transform: translateX(-60%); }
}

Compatibilidad con Navegadores y Patrones de Fallback Elegantes

Seamos honestos sobre el panorama actual (a mediados de 2025):

  • Chrome/Edge 115+: Soporte completo ✅
  • Firefox: Lanzado en Firefox 110+ detrás de una bandera; soporte completo sin bandera llegó en Firefox 126 ✅
  • Safari: Parcial — los timelines scroll() llegaron en Safari 18, el soporte de view() aún está en progreso ⚠️

Esto significa que aproximadamente el 85-90% del tráfico global de navegadores puede renderizar animaciones CSS de scroll de forma nativa. Es un número viable para producción — si gestionas el fallback correctamente.

El Patrón @supports

Envuelve los estilos de animación scroll-driven en una consulta de funcionalidad:

/* Estilos base — siempre visibles, sin animación */
.card {
  opacity: 1;
  transform: none;
}

/* Experiencia mejorada para navegadores compatibles */
@supports (animation-timeline: scroll()) {
  .card {
    opacity: 0;
    transform: translateY(30px);
    animation: card-reveal both ease-out;
    animation-timeline: view();
    animation-range: entry 10% entry 50%;
  }
}

Esta es la estrategia de mejora progresiva: los navegadores sin soporte ven la página estática, completamente legible. Los navegadores compatibles obtienen la capa cinematográfica por encima. Ningún contenido queda oculto para nadie.

Cuándo Cargar un Polyfill

El polyfill de scroll-driven-animations mantenido por el equipo de Chrome proporciona un fallback basado en JS para navegadores más antiguos con una fidelidad razonable. Cárgalo de forma condicional:

if (!CSS.supports('animation-timeline: scroll()')) {
  import('/polyfills/scroll-timeline.js');
}

Esto mantiene tu bundle principal limpio mientras amplías el alcance donde sea necesario.


Cuándo Recurrir a JavaScript de Todos Modos

Nada de esto significa que las librerías de scroll en JavaScript estén obsoletas. Existen casos de uso genuinos donde las CSS Scroll-Driven Animations topan con un muro:

  • Timelines secuenciadas complejas — La API de timeline de GSAP te permite encadenar docenas de animaciones con callbacks, condiciones y valores dinámicos. CSS no tiene un flujo de control equivalente.
  • Lógica disparada por scroll, no solo efectos visuales — Cargar datos cuando un elemento entra en el viewport, registrar eventos de analítica, activar audio — estos son asuntos de JS.
  • Animaciones basadas en física o con resortes — Momentum, inercia, rebote elástico. La propiedad animation-timing-function de CSS es expresiva pero limitada comparada con un motor de física apropiado.
  • Campañas críticas en Safari — Si las analíticas de tu cliente muestran más de un 30% de tráfico en Safari, quizás quieras usar GSAP como controlador principal con CSS como objetivo de migración futura.
  • Contenido dinámico con estructura DOM desconocida — Cuando no puedes predecir qué elementos existirán en tiempo de construcción, la flexibilidad en tiempo de ejecución de JavaScript gana.

La decisión correcta en 2025 no es "CSS vs. JavaScript" — es "CSS primero, JavaScript donde CSS se queda sin camino."


Conclusión: La Especificación Está Lista. ¿Y Tú?

Las CSS Scroll-Driven Animations representan una de las adiciones más significativas a la especificación CSS en años — no porque introduzcan efectos visuales vistosos nuevos, sino porque le dan al compositor del navegador la propiedad completa del movimiento vinculado al scroll. El resultado son experiencias más fluidas con menos código, bundles más pequeños y sin ningún presupuesto de eventos de scroll que gestionar.

Para las agencias creativas, esto es una ventaja competitiva a plena vista. Los estudios que aún envían cada encabezado parallax a través de GSAP están pagando un coste de rendimiento que sus clientes nunca pidieron. La receta es sencilla: adopta las animaciones CSS de scroll como tu opción predeterminada, usa @supports para delimitar la experiencia mejorada y reserva JavaScript para los casos donde genuinamente necesitas lógica en tiempo de ejecución.

Empieza con la barra de progreso de lectura — requiere cuatro líneas de CSS, se lanza hoy, y hará que cada desarrollador de tu equipo se pregunte inmediatamente qué más es posible. Esa curiosidad es exactamente adonde esta especificación merece llevarte.

El renacimiento de las animaciones de scroll ya está aquí. Solo que no requiere una etiqueta <script>.