The CSS scroll-timeline-axis property allows you to set which scroll direction triggers an animation. You can animate elements when they scroll horizontally (along the x-axis) or vertically (along the y-axis).
.scroll-container {
scroll-timeline-name: --side-scroller; /* gives the timeline a name */
scroll-timeline-axis: x; /* horizontal axis */
}
.animated-element {
animation: /* references the animation keyframes that are used */
animation-timeline: --side-scroller /* initiates the scroll timeline */
}
The scroll-timeline-axis property is defined in Scroll-Driven Animations Module Level 1 which is currently in Editor’s Draft. This means the content may change between now and when it formally becomes a Candidate Recommendation, even though scroll-driven animations themselves are broadly supported.
Gotchas
There are a couple things worth knowing when you use the scroll-timeline-axis property:
It doesn’t actually change scrolling
This property doesn’t change how the browser or the element’s scroll container actually scrolls, but simply says, “Hey, Browser! When this scroll container moves in this direction, trigger any animations attached to that
scroll-timeline.
Set it on the scroll container
It’s also worth noting that the property should be set on the scroll container and not an element that is being scrolled into view (unlike a view timeline which goes on the element being scrolled into view, not the scroll container).
Syntax
scroll-timeline-axis: [ block | inline | x | y ]#
- Initial:
block - Applies to: all elements
- Inherited: no
- Percentages: n/a
- Computed value: a list of the keywords specified
- Canonical order: per grammar
- Animation type: not animatable
Values
/* Keyword values */
scroll-timeline-axis: block; /* vertical in English, but depends on writing-mode */
scroll-timeline-axis: inline; /* horizontal in English, but depends on writing-mode */
scroll-timeline-axis: x; /* horizontal */
scroll-timeline-axis: y; /* vertical */
/* Global values */
scroll-timeline-axis: inherit;
scroll-timeline-axis: initial;
scroll-timeline-axis: revert;
scroll-timeline-axis: revert-layer;
scroll-timeline-axis: unset;
Logical values (responds to the writing mode):
block(default): Vertical direction for languages like English that are read left-to-right (or right-to-left languages), but will be horizontal for languages that are read top-to-bottom.inline: Horizontal direction for languages like English that are read left-to-right (or right-to-left languages), but will be vertical for languages that are read top-to-bottom.
Physical values (the same, no matter the writing mode)
x: Horizontal directiony: Vertical direction
Basic usage
The scroll-timeline-axis property is just one piece of the overall animation. To use it, you need a few pieces working together:
- Name the timeline with
scroll-timeline-name. - Set the axis with
scroll-timeline-axis. - 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: --side-scroller; /* must name the animation */
scroll-timeline-axis: x; /* triggers the animation on horiztonal scroll */
animation: swim; /* references a set of animation keyframes */
animation-timeline: --side-scroller; /* reference the timeline name */
}
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).
Demo
The following demo shows how we can run an animation when scrolling along the horizontal x-axis. Scroll outside the container to open and close the book:
The .scrollcontainer div is the one within which we’ll be scrolling so that’s where we set the scroll-timeline-name and the scroll-timeline-axis.
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 @supports the animation-timeline and animation-range properties to cover all our bases:
@supports ((animation-timeline: scroll()) and (animation-range: 0% 100%)) {
/* Animation styles go here */
}
Related
animation-timeline
.element { animation-timeline: --imageTimeline; }
scroll-timeline-axis
.scroll-container { scroll-timeline-axis: x; }
scroll-timeline-name
.element { scroll-timeline-name: --scroller; }
timeline-scope
.common-ancestor { timeline-scope: --my-timeline; }
view-timeline-name
.element { view-timeline-name: --image-zoom; }
scroll()
.element { animation-timeline: scroll(); }