¿Cómo funciona?
La magia está en animation-timeline: scroll().
En lugar de que la animación corra con el tiempo, corre con la posición del scroll.
Cuando llegas al fondo → la animación está al 100%.
.mi-linea { animation: crecer linear; /* ← esto es TODO lo que necesitas */ animation-timeline: scroll(); } @keyframes crecer { from { transform: scaleX(0); } to { transform: scaleX(1); } }
El parámetro de scroll() puede ser:
animation-timeline: scroll(root); /* scroll de la página entera */ animation-timeline: scroll(nearest); /* scroll del contenedor más cercano */ animation-timeline: scroll(self); /* scroll del propio elemento */
Línea horizontal
El truco: usar transform: scaleX()
con transform-origin: left
para que crezca de izquierda a derecha.
↑ Esta línea se llena a medida que haces scroll
.linea { height: 3px; background: linear-gradient(90deg, cyan, magenta); transform-origin: left; /* crece desde la izquierda */ transform: scaleX(0); /* empieza invisible */ animation: grow-x linear; animation-timeline: scroll(root); } @keyframes grow-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }
Dibujar un path SVG
Para líneas curvas o irregulares, la técnica clásica usa
stroke-dashoffset.
Define el dash tan largo como el path, luego anímalo a 0.
.mi-path { fill: none; stroke: cyan; stroke-dasharray: 1000; /* longitud total del path */ stroke-dashoffset: 1000; /* empieza "borrado" */ animation: draw linear; animation-timeline: scroll(root); } @keyframes draw { from { stroke-dashoffset: 1000; } to { stroke-dashoffset: 0; } }
💡 Para saber la longitud exacta del path en JavaScript:
path.getTotalLength()
animation-range
Por defecto la animación corre durante todo el scroll.
Con animation-range
puedes definir en qué porcentaje empieza y termina.
.linea-a { animation: grow-x linear; animation-timeline: scroll(root); animation-range: 0% 50%; /* termina a mitad del scroll */ } .linea-b { animation: grow-x linear; animation-timeline: scroll(root); animation-range: 50% 100%; /* empieza a mitad del scroll */ }
Subrayado de texto
Un uso elegante: revelar subrayados en palabras clave mientras el usuario lee.
Diseño moderno,
código limpio,
scroll animado.
.palabra { position: relative; display: inline; } .palabra::after { content: ''; position: absolute; bottom: -2px; left: 0; width: 100%; height: 2px; background: cyan; transform-origin: left; transform: scaleX(0); animation: reveal linear; animation-timeline: scroll(root); animation-range: 60% 90%; /* aparece cerca del final */ }
Cheat Sheet
| Técnica | Propiedad clave | Úsala cuando… |
|---|---|---|
| Línea div | transform: scaleX() | Líneas simples horizontales/verticales |
| SVG path | stroke-dashoffset | Líneas curvas o formas personalizadas |
| Subrayado | ::after + scaleX() | Destacar palabras en texto |
| Borde animado | background-position | Cards con bordes de colores |
| Rango parcial | animation-range | Activar en una sección específica |
animation-timeline está soportado en Chrome 115+, Edge 115+, Firefox 110+ (con flag) y Safari aún no lo soporta nativamente.
Para producción, considera usar un fallback con JavaScript (Intersection Observer) o la librería Motion One.