CSS Scroll-Driven Write-on Text Effect

CSS scroll-driven animations are a new feature that's in early days of rolling out to browsers. In short, they’re everything we love about CSS animations, but with a timeline based on scroll position instead of automatic timeline.

This is my first time tinkering with them and so far they’re super fun. Being able to accomplish these effects with zero JavaScript is huge. This type of text write-on effect is very common in animation. Trying it with scroll animations was one of the first things that popped into my head.

Note: At the time of this post, CSS scroll-driven animations support is limited to Chrome 116+ which is only in Chrome Canary.

Here’s the demo. It’s not perfect, but workable. A proper write-on text effect would have the actual stroke of the letters written out instead of just a reveal like this.

See the Pen CSS scroll-driven text write-on by Tyler Gaw (@tylergaw) on CodePen.

And a video showing the effect if you don't want to mess with Chrome Canary.

While it takes time to figure out the nuances of how scroll animations work, this demo is fairly straightforward to accomplish. I’m animating the width of a clip-path polygon to reveal each line of text. Instead of the animation running immediately, the progress of it is tied to the scroll position of the p element for the line of the poem.

The full code is available in the CodePen, the core bits are as follows:

@keyframes write {
  0% { clip-path: polygon(0 0, 0 0, 0 100%, 0 100%); }
  100% { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); }

main p {
  animation: write linear both;
  view-timeline-name: --written-text;
  view-timeline-axis: block;
  animation-timeline: --written-text;
  animation-range: entry-crossing 30% contain 45%;
  1. Declare a @keyframes animation named write that increases the width of a clip-path from 0 to 100%.
  2. Apply the write animation to each p
  3. Give the timeline a unique name, --written-text, and set that as the animation-timline. This overrides the standard, automatic animation timeline
  4. Using animation-range, refine how the animation progresses related to the scroll position of each p

That last point for animation-range, that’s where I spent the most time. And where we have the most control over each animation. There’s a ton of different possible variations. Luckily Bramus made an excellent tool to visualize it.

This is just one effect that’s possible with scroll-driven animations. Another very welcome addition to CSS. If you’re looking for an intro to them, again Bramus has you covered with “Animate elements on scroll with Scroll-driven animations”.