- Es posible implementar animaciones vinculadas al scroll solo con CSS, sin JS ni librerías adicionales
- Con propiedades CSS como animation-timeline: scroll() / view(), la animación avanza según la posición del scroll o la entrada al viewport
- La propiedad animation-range permite ajustar en detalle en qué tramo del viewport empieza y termina la animación
- Para usuarios sensibles al movimiento, se recomienda usar la media query prefers-reduced-motion
- Desde Safari 26 beta hay soporte, lo que amplía mucho el alcance de uso de las animaciones de scroll basadas en CSS
Los 3 elementos de la animación basada en scroll
- Target: el elemento objetivo al que se aplicará la animación (por ejemplo, una barra de progreso o una imagen)
- Keyframes: define qué cambios ocurrirán según el scroll (igual que en
@keyframesde CSS tradicional) - Timeline: determina cuándo y cómo avanza la animación (basado en scroll/vista, no en tiempo)
Timeline en CSS
- Las animaciones CSS tradicionales usan por defecto la document timeline (basada en tiempo)
- Con la introducción de la propiedad animation-timeline (CSS Animations Level 2, 2023), ahora es posible hacer que la animación avance según criterios distintos al tiempo, como el scroll o la entrada al viewport
timeline scroll()
- La timeline scroll() hace que la animación avance solo cuando el usuario hace scroll
- Ejemplo: una barra de progreso inferior que se llena de izquierda a derecha conforme se hace scroll
footer::after { content: ""; height: 1em; width: 100%; background: rgba(254, 178, 16, 1); left: 0; bottom: 0; position: fixed; animation: grow-progress linear; animation-timeline: scroll(); } @keyframes grow-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } } - animation-timeline debe definirse después de la propiedad animation para que funcione correctamente
Consideraciones de accesibilidad para movimiento
- Para proteger a usuarios sensibles al movimiento, se recomienda usar la media query prefers-reduced-motion
@media not (prefers-reduced-motion) { /* código de animación */ }
timeline view()
- La timeline view() inicia la animación cuando el elemento objetivo aparece en el viewport
- Ejemplo: al hacer scroll, una imagen se desliza desde la derecha y aparece gradualmente
@keyframes slideIn { 0% { transform: translateX(100%); opacity: 0; } 100% { transform: translateX(0%); opacity: 1; } } img { animation: slideIn; animation-timeline: view(); }
Control del tramo de avance con animation-range
-
De forma predeterminada,
animation-rangeva de 0% (entrada al viewport) a 100% (salida completa) -
Ejemplo: hacer que la animación avance solo hasta el tramo del 50% del viewport
img { animation: slideIn; animation-timeline: view(); animation-range: 0% 50%; } -
Para una buena experiencia de usuario, es necesario ajustar valores adecuados de
range -
Si se considera la accesibilidad de movimiento, conviene usarlo junto con prefers-reduced-motion
@media not (prefers-reduced-motion) { img { animation: slideIn; animation-timeline: view(); animation-range: 0% 50%; } }
Uso avanzado y siguientes pasos
scroll()yview()son funciones, y permiten especificar varias opciones como el elemento scroller (predeterminado:nearest) o el eje (block,inline,x,y)- Con
animation-range,entry/exity otros, se puede construir una UX mucho más precisa - El soporte inicial está llegando en navegadores recientes como Safari 26 beta, y se espera que con el tiempo aumenten la estandarización y la compatibilidad
2 comentarios
Se puede implementar solo con
animation-timeline. ¡Qué curioso!