Animaciones CSS impulsadas por desplazamiento: 5 patrones de animación de desplazamiento con CSS puro sin JavaScript

前端工程(Actualizado el 14 jul 2026)

Animaciones CSS Impulsadas por Desplazamiento: Desplazamiento Suave Sin JS

Parallax con listeners de desplazamiento JS causando tartamudeo, código verboso de IntersectionObserver, sobrecarga de rendimiento de requestAnimationFrame — las animaciones de desplazamiento han dependido durante mucho tiempo de JavaScript. Las animaciones CSS impulsadas por desplazamiento te permiten implementar parallax, barras de progreso y animaciones de revelación puramente en CSS: cero JS, 60fps, aceleración GPU automática. En 2026, las animaciones CSS impulsadas por desplazamiento son totalmente soportadas en Chrome y Safari.

Este artículo cubre 5 patrones principales, guiándote a través de scroll-timeline → view-timeline → parallax → indicador de progreso → animaciones de revelación.


Conceptos Básicos

Concepto Descripción
scroll-timeline Línea de tiempo de animación basada en la posición de desplazamiento
view-timeline Línea de tiempo de animación basada en la visibilidad del elemento
animation-timeline Especifica qué línea de tiempo de desplazamiento usa una animación
animation-range Posiciones de inicio y fin de la animación dentro del rango de desplazamiento
scroll() Función de línea de tiempo de desplazamiento anónima
view() Función de línea de tiempo de vista anónima
scroll-progress Progreso de desplazamiento 0-1
view-progress Progreso de visibilidad 0-1

Análisis del Problema: 5 Desafíos Principales de Animación de Desplazamiento CSS

  1. Compatibilidad de navegadores: El soporte de Firefox va por detrás
  2. Depuración difícil: El soporte de DevTools para animaciones de desplazamiento es limitado
  3. Desplazamiento anidado: La configuración de contenedores de desplazamiento que no son del documento es compleja
  4. Cálculo del rango de animación: El porcentaje de animation-range tiene alto costo de comprensión
  5. Fallback: Los navegadores no soportados necesitan fallback con JS

Paso a Paso: 5 Patrones de Animación de Desplazamiento CSS

Patrón 1: Animación de Progreso de Desplazamiento con scroll-timeline

/* Barra de progreso superior de la página */
@keyframes progress-bar {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 3px;
  background: linear-gradient(90deg, #6366f1, #ec4899);
  transform-origin: left;
  animation: progress-bar linear;
  animation-timeline: scroll(root);
}

Patrón 2: Animación de Revelación en Viewport con view-timeline

@keyframes reveal-up {
  from {
    opacity: 0;
    transform: translateY(60px) scale(0.95);
    filter: blur(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0);
  }
}

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

Patrón 3: Efecto de Desplazamiento Parallax

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

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

.parallax-bg {
  animation: parallax-slow linear both;
  animation-timeline: scroll(root);
}

.parallax-fg {
  animation: parallax-fast linear both;
  animation-timeline: scroll(root);
}

Patrón 4: Línea de Tiempo de Desplazamiento Nombrada

.scroller {
  overflow-y: auto;
  scroll-timeline-name: --my-scroller;
  scroll-timeline-axis: block;
}

@keyframes rotate-icon {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.rotating-icon {
  animation: rotate-icon linear;
  animation-timeline: --my-scroller;
}

Patrón 5: Secuencias de Animación Complejas

@keyframes hero-sequence {
  0% {
    opacity: 0;
    transform: translateY(100px) scale(0.8);
    filter: blur(10px);
  }
  30% {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0);
  }
  70% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  100% {
    opacity: 0;
    transform: translateY(-50px) scale(0.95);
  }
}

.hero-title {
  animation: hero-sequence linear both;
  animation-timeline: view();
  animation-range: entry 0% exit 100%;
}

Guía de Problemas Comunes

Problema 1: No especificar animation-timeline

/* ❌ Incorrecto: falta animation-timeline */
.element {
  animation: slide-in 1s linear;
  /* La animación no seguirá el desplazamiento */
}

/* ✅ Correcto: especificar línea de tiempo de desplazamiento */
.element {
  animation: slide-in linear both;
  animation-timeline: view();
}

Problema 2: Valores incorrectos de animation-range

/* ❌ Incorrecto: el rango excede el rango de desplazamiento */
.element {
  animation-range: entry 0% entry 200%; /* 200% inválido */
}

/* ✅ Correcto: usar rango válido */
.element {
  animation-range: entry 0% entry 100%;
}

Problema 3: Transform en conflicto con el desplazamiento

/* ✅ Correcto: usar sugerencia will-change */
.parallax {
  animation: parallax linear both;
  animation-timeline: scroll(root);
  will-change: transform;
}

Problema 4: No manejar el fallback

/* ✅ Correcto: proporcionar fallback */
@supports (animation-timeline: view()) {
  .card {
    animation: reveal-up linear both;
    animation-timeline: view();
  }
}

@supports not (animation-timeline: view()) {
  .card { opacity: 1; transform: none; }
}

Problema 5: Contenedor de desplazamiento sin overflow

/* ✅ Correcto: asegurar que el contenedor sea desplazable */
.scroller {
  overflow-y: auto;
  scroll-timeline-name: --my-scroll;
}

Solución de Errores

# Error Causa Solución
1 La animación no sigue el desplazamiento No se estableció animation-timeline Agregar animation-timeline: view() o scroll()
2 La animación termina prematuramente animation-range demasiado pequeño Aumentar el rango
3 Dirección de parallax incorrecta scroll-timeline-axis mal configurado Usar block/inline para la dirección
4 Línea de tiempo nombrada inválida scroll-timeline-name no coincide Asegurar que los nombres padre-hijo coincidan
5 Tartamudeo de animación Sin will-change Agregar will-change: transform
6 Firefox no funciona El navegador no soporta Usar @supports para fallback
7 Desplazamiento anidado no funciona Conflicto de desplazamiento interno/externo Usar scroll-timeline nombrado
8 Salto de animación Keyframes no lo suficientemente suaves Agregar más keyframes o usar linear
9 Elementos fijos anormales transform afecta el posicionamiento fijo Mover elementos fijos fuera del contenedor transform
10 Móvil no fluido Aceleración GPU no habilitada Agregar transform: translateZ(0)

Optimización Avanzada

  1. Scroll Snap + Animaciones de Desplazamiento: Combinar desplazamiento paginado con animaciones
  2. Propiedades personalizadas CSS Houdini: Registrar propiedades de animación para efectos complejos
  3. prefers-reduced-motion: Respetar la preferencia del usuario de movimiento reducido
  4. Container queries + animaciones de desplazamiento: Sinergia responsiva y de animación de desplazamiento
  5. WAAPI + Scroll Timeline: Web Animations API combinada con líneas de tiempo de desplazamiento CSS

Comparación

Dimensión CSS Scroll-Driven JS IntersectionObserver Evento scroll JS GSAP ScrollTrigger
Rendimiento ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐
Volumen de código ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐
Soporte de navegadores ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Flexibilidad ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Facilidad de depuración ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐
Curva de aprendizaje ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐

Resumen: Las animaciones CSS impulsadas por desplazamiento te permiten lograr efectos de desplazamiento suaves con cero JS, superando ampliamente a las soluciones JS. Las animaciones de desplazamiento CSS son adecuadas para escenarios de interacción de desplazamiento que buscan rendimiento extremo, especialmente parallax, barras de progreso y animaciones de revelación. Con soporte completo de Chrome y Safari en 2026, usar con fallback @supports.


Herramientas en Línea

Prueba estas herramientas que se ejecutan en tu navegador — no requieren registro →

#scroll-timeline#视差效果#滚动动画#CSS动画#2026#前端工程