jun 02, 2026
🔗 CSS-native parallax effect
Parallax effects have a long history, and while there are countless ways and libraries to achieve them, a new CSS-native way was recently made possible with CSS Scroll-driven animation timelines.
The usual recipe was a scroll event listener in JavaScript, recalculating positions on every frame and nudging an element up and down.
Scroll-driven animations handle all of that with CSS. Handling parallax animations with CSS has a few advantages: performance should be better as it runs it off the main thread, but my favorite part is the simplicity with which the whole thing becomes a small block of declarative styles, that can be applied with a single utility class. Here is the full code for the class:
.parallax { view-timeline-name: --parallax-tl; view-timeline-axis: block ; overflow: hidden ; & > * { scale: calc ( 1 + var ( --parallax-offset , 20 ) * 2 / 100 ); animation: parallax auto linear both ; animation-timeline: --parallax-tl; animation-range: cover ; will-change: translate; } } @keyframes parallax { from { translate: 0 calc ( var ( --parallax-offset , 20 ) * -1 % ); } to { translate: 0 calc ( var ( --parallax-offset , 20 ) * 1 % ); } }
# The timeline
The trick is view-timeline-name . It creates a view progress timeline, a timeline whose progress is measured by how far the .parallax element has travelled through the scrollport. It reads 0% the moment the element starts to enter the viewport and 100% once it has fully left. view-timeline-axis: block tells it to track movement along the block axis, which is the vertical one in a normal writing mode.
On the child, animation-timeline: --parallax-tl swaps the animation's clock from time to that timeline. From there the rest of the animation line falls into place:
auto for duration, because the duration now comes from the timeline rather than a number of seconds
... continue reading