Skip to content
Tech News
← Back to articles

CSS-Native Parallax Effect

read original get CSS Parallax Scrolling Kit → more articles
Why This Matters

The introduction of CSS-native parallax effects using scroll-driven animation timelines marks a significant advancement in web design. This approach offers improved performance and simplicity by eliminating JavaScript dependencies, enabling developers to create smooth, efficient parallax effects with declarative CSS styles. As a result, both developers and consumers benefit from more responsive and visually engaging websites with less code complexity.

Key Takeaways

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