CSS view-timeline-axis Property

Sets the specific scroll axis that will be used to track an element's progress through the visible area for scroll-driven animations.

selector { view-timeline-axis: value; }
block Specifies the axis in the block direction of the writing mode, which is vertical in standard top-to-bottom layouts.
inline Specifies the axis in the inline direction of the writing mode, which is horizontal in standard left-to-right layouts.
y Forces the scroll timeline to track movement along the vertical axis regardless of writing mode.
x Forces the scroll timeline to track movement along the horizontal axis regardless of writing mode.

Code Examples

A basic example showing how to trigger a fade-in animation as a red box enters the vertical scroll view.

<style>
.scroll-container {
  height: 400px;
  overflow-y: scroll;
  background: #f4f4f4;
}
.spacer {
  height: 800px;
}
.reveal-box {
  width: 100px;
  height: 100px;
  background: #ff0000;
  view-timeline-name: --revealer;
  view-timeline-axis: block;
  animation: fade-in linear both;
  animation-timeline: --revealer;
}
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
</style>
<div class="scroll-container">
  <div class="spacer"></div>
  <div class="reveal-box"></div>
  <div class="spacer"></div>
</div>

An advanced horizontal gallery where items scale up as they pass the center of the viewport, including a JS toggle for the axis.

<style>
.gallery {
  display: flex;
  overflow-x: auto;
  width: 100%;
  gap: 20px;
}
.item {
  flex: 0 0 300px;
  height: 200px;
  background: #007bff;
  view-timeline-name: --item-scan;
  view-timeline-axis: inline;
  animation: scale-up linear both;
  animation-timeline: --item-scan;
}
@keyframes scale-up {
  0% { transform: scale(0.5); }
  50% { transform: scale(1); }
  100% { transform: scale(0.5); }
}
</style>
<div class="gallery" id="mainGallery">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
<script>
const gallery = document.getElementById("mainGallery");
gallery.addEventListener("click", () => {
  const items = document.querySelectorAll(".item");
  items.forEach(item => {
    item.style.viewTimelineAxis = "x";
    console.log("Axis explicitly set to X for horizontal tracking");
  });
});
</script>

Pro Tip

You can use the shorthand view-timeline property to set both the name and the axis in a single line, keeping your CSS clean and much easier to manage.

Deep Dive

Think of view-timeline-axis as choosing which lane a finish-line camera is watching. When an element enters the viewport, the browser needs to know if it should measure progress based on vertical scrolling or horizontal scrolling. By setting this property, you define the orientation of the 'tripwire' that triggers the animation progress. Without it, the browser defaults to the block axis, which usually means vertical scrolling. It works hand-in-hand with view-timeline-name to establish a complete scroll-progress timeline linked to the visibility of a specific element.

Best Practices

Stick to the block keyword for standard websites to ensure the animation maps to the natural scrolling behavior of the user. Only use x or y when you are building specific creative components like horizontal carousels or side-scrolling galleries where the writing mode might not match the physical scroll direction.

Common Pitfalls

This property does absolutely nothing on its own; you must also define a view-timeline-name. Another common mistake is choosing the wrong axis for a container that does not have overflow scrolling enabled in that direction, which results in the animation never firing because progress never reaches 1%.

Accessibility

Scroll-driven animations can cause motion sickness for some users. Always wrap your animation logic in a media query that checks for prefers-reduced-motion: no-preference to ensure you are not forcing movement on people who find it disorienting.

Dev Data Table: view-timeline-axis property

default block
animatable no
inherited no
experimental yes
year_intro 2022
year_standard 0
js_syntax_1 element.style.viewTimelineAxis
js_syntax_2 element.style.setProperty("view-timeline-axis", "y")
js_note This property is often updated in tandem with view-timeline-name to dynamically switch between horizontal and vertical scroll triggers.
browsers { "Chrome": "115", "Edge": "115", "Firefox": "114", "Safari": "18", "Opera": "101", "Chrome Android": "115", "Safari on iOS": "18", "Samsung Internet": "23", "Opera Mobile": "77" }
results render here...