view-timeline-axis

John Rhea on

The view-timeline-axis CSS property allows you to set which direction an animation scrolls when triggered. You can animate elements when they scroll horizontally (along the x-axis) or vertically (along the y-axis).

It’s important to note that 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, start the animation on this element.” It’s also worth noting that the property should be set on the animated element itself, not the scroll container within which it is scrolled — the scroll container is typically the parent or ancestor of the element which is scrolled.

.element {
  view-timeline-name: --side-scroller; /* gives the timeline a name */
  view-timeline-axis: x; /* horizontal axis */

  animation: /* references the animation keyframes that are used */
  animation-timeline: --side-scroller /* initiates the view timeline */
}

view-timeline-axis is defined in Scroll-driven Animations Module Level 1 which is currently in Editor’s Draft. This means the content is pretty early on in the drafting process and may change between now and when it formally becomes a Candidate Recommendation.

Demo

The following demo shows how we can run an animation when scrolling along the horizontal x-axis:

Syntax

view-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 */
view-timeline-axis: block; /* vertical in English, but depends on writing-mode */
view-timeline-axis: inline; /* horizontal in English, but depends on writing-mode */
view-timeline-axis: x; /* horizontal */
view-timeline-axis: y; /* vertical */

/* Global values */
view-timeline-axis: inherit;
view-timeline-axis: initial;
view-timeline-axis: revert;
view-timeline-axis: revert-layer;
view-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 direction
  • y: Vertical direction

Note: While I have seen the keyword “horizontal” used in an MDN code example, “horizontal” is not in the specification, at least not as of this writing. Only the four above values are.

How it works

The view-timeline-axis property is just one piece of the overall animation. To use it, you need three pieces working together:

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

.example {
  view-timeline-name: --side-scroller; /* must name the animation */
  view-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: animation-timeline must be set separately from and after animation. The shorthand animation will reset animation-timeline, but animation-timeline cannot (at least at the time of this writing) be set within the shorthand.

Example: Flipping cards

Let’s say you have a series of cards facing backwards that you want to flip forward to reveal the other side as the user scrolls horizontally. Setting the view-timeline-axis can allow these cards to flip as they enter the scrollport (the scrollable area of the container).

Again, browser support is a little iffy as of January 2026. That demo should work for you in the latest Chrome and Safari, but it’s a no-go in Firefox, at least as I’m writing this. Keep an eye on browser support.

Fine-tuning with animation-range

There’s also a newer animation-range property that allows you to determine exactly where on the timeline the animation begins. For example, we can offset the animation by 500px so that it is triggered further to the left side of the x-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 */
}