scroll-timeline-name

John Rhea on

The CSS scroll-timeline-name property allows you to name a scroll timeline, which in turn, lets you drive animations based on the scrolling of that element.

.element {
  scroll-timeline-name: --scroller; /* must name the animation */

  animation: progress-bar; /* references a set of animation keyframes */
  animation-timeline: --scroller; /* reference the timeline name */
}

For instance, in this demo, the length of the html element is the timeline across which the card flip animation plays.

Syntax

Value: [ none | <dashed-ident> ]#
  • Initial value: none
  • Applies to: all elements
  • Inherited: no
  • Percentages: n/a
  • Computed value: the keyword none or a list of CSS identifiers
  • Canonical order: per grammar
  • Animation type: not animatable

Values

scroll-timeline-name: none;
scroll-timeline-name: --name-of-the-timeline;
  • none: The default value.
  • <dashed-ident>: A name starting with a double dash (just like a CSS custom property, e.g. --my-property). With this, you are identifying the scrolling of the element you put this property on as a timeline for an animation. The first keyframe of that animation begins at the top or left side of the scroll (depending on whether you’re scrolling vertically or horizontally) and ends at the bottom or right side of the scroll. Any keyframe between the beginning and end will fall at the same percentage of the scroll, e.g. a 37% keyframe will happen 37% of the way through scrolling of this element, the scroll container.

The animation can be, and often is, on a completely different element than the timeline is set. For instance, the card in the top demo is tied to the scroll of the HTML element.

Basic usage

The scroll-timeline-name property is just one piece of the overall animation. To use it, you need to reference the timeline in your animation with animation-timeline.

Here’s a complete example (except the actual animation keyframes, for brevity):

.example {
  scroll-timeline-name: --scroller; /* must name the animation */

  animation: progress-bar; /* references a set of animation keyframes */
  animation-timeline: --scroller; /* reference the timeline name */
}

And, as far as usage goes, scroll-timeline-name and scroll-timeline-axis can be combined into a single declaration using the scroll-timeline shorthand property.

Note: The animation-timeline property should be set separately from and after animation. Otherwise, the animation shorthand property will reset the animation-timeline property and, unfortunately, animation-timeline cannot be set on the shorthand (at least not at the time of this writing).

Example: Adaptive progress bars

In this demo, the super zombie flies across the top of the screen as you progress down the page. Fancy that, it’s a progress bar!

It might be possible, under specific conditions, to time this in such a way as to get it to work with just CSS, but we live in a responsive world. Not only that, what if the length of the text changes in the middle of the page because you inadvertently included a details element after the first paragraph that those pesky users can open at will, destroying all your magic numbers and arbitrary choices. shakes fist at users and their hoity-toity presumption that a website should work

But with scroll-based timelines no matter how dynamic the height of the content, it will always match the length of the timeline. If you scroll to the details element, you’ll notice that when you open it, the super zombie moves back just a bit because the html element on which we’ve named the scroll timeline has expanded to include the height of the open details element. If you then close the details element, the super zombie moves forward, commensurate with the change in size of a closed details element.

Scroll timelines vs. View timelines (cage match)

View timelines are very similar to scroll timelines, but the timeline only covers when the scrolled element is in view.

In the above demo, the magenta punch line on the left shows when the animation is running based on scrolling of the entire HTML document. On the right, the punches are tied to when the much shorter punch lines are in view. A punch is completed every time the short punch lines traverse the viewport

One big difference between the two when building a scroll based animation is where you define the timeline. A scroll-timeline should be set on the scroll container whereas a view timeline goes on the element being scrolled.

Name collisions

A named timeline is valid within the element it is named and on all of its children.

If more than one element has the same named timeline, the one declared on the closest element will be used. If an element has a conflict within itself, whichever timeline is declared last wins. And should there still be a conflict a scroll timeline will take precedence over a view timeline.

Browser support

Always test your scroll-driven animations thoroughly before deploying to production, and consider providing fallbacks for unsupported browsers.

We can provide a fallback by checking whether the browser @supportstheanimation-timeline` and animation-range properties to cover all our bases:

@supports ((animation-timeline: scroll()) and (animation-range: 0% 100%)) {
  /* Animation styles go here */
}