How To Create Scroll-Driven Animations With Css Animation-Timeline
Scroll-driven animations link the progress of a CSS animation to the scroll position or to the visibility of an element. They run off the main thread, so they are smoother than JavaScript scroll listeners and need no IntersectionObserver.
Reveal an element as it enters the screen
css">@keyframes lotgrafix-reveal {
from {
opacity: 0;
transform: translateY( 40px );
}
to {
opacity: 1;
transform: translateY( 0 );
}
}
@supports ( animation-timeline: view() ) {
.lotgrafix-reveal {
animation: lotgrafix-reveal linear both;
animation-timeline: view();
animation-range: entry 0% cover 30%;
}
}
Reading progress bar
<div class="lotgrafix-progress"></div>
@keyframes lotgrafix-grow {
from { transform: scaleX( 0 ); }
to { transform: scaleX( 1 ); }
}
.lotgrafix-progress {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: orangered;
transform-origin: 0 50%;
animation: lotgrafix-grow linear both;
animation-timeline: scroll( root );
}
Key properties
animation-timeline: scroll(): progress follows the scroll position of a container.animation-timeline: view(): progress follows how much the element is visible in the viewport.animation-range: defines which part of the scroll or visibility range drives the animation, for exampleentry,exitorcover.
Always respect reduced motion
@media ( prefers-reduced-motion: reduce ) {
.lotgrafix-reveal,
.lotgrafix-progress {
animation: none;
}
}
Support note
Use @supports as shown above. Browsers without support skip the animation and show the normal final state, so content is never hidden.
November 3, 2026


