CSS scroll-timeline-name Property

The scroll-timeline-name property assigns a specific name to a scroll progress timeline on a scrollable element, allowing other elements to sync their animations to its scroll position.

selector { scroll-timeline-name: --custom-name; }
none The element has no named scroll progress timeline associated with it.
<dashed-ident> A user-defined name for the timeline, which must start with two dashes to distinguish it from standard CSS keywords.

Code Examples

A basic example showing a progress bar that fills up as you scroll through a specific container.

<style>
.scroll-container {
  height: 300px;
  overflow-y: scroll;
  scroll-timeline-name: --main-timeline;
  border: 5px solid #333333;
}
.content {
  height: 1000px;
  background: linear-gradient(#ffffff, #000000);
}
.progress-bar {
  height: 20px;
  background: #00ff00;
  width: 0%;
  position: fixed;
  top: 0;
  animation: grow auto linear;
  animation-timeline: --main-timeline;
}
@keyframes grow {
  to { width: 100%; }
}
</style>
<div class="progress-bar"></div>
<div class="scroll-container">
  <div class="content">Scroll down to see the bar grow.</div>
</div>

An advanced example using JavaScript to dynamically update the scroll-timeline-name and re-link an animated element to the new identifier.

<style>
#scroller {
  height: 200px;
  overflow: auto;
  scroll-timeline-name: --dynamic-timeline;
  background: #f0f0f0;
}
.box {
  width: 50px;
  height: 50px;
  background: #ff0000;
  animation: rotate auto linear;
  animation-timeline: --dynamic-timeline;
}
@keyframes rotate {
  to { transform: rotate(360deg); }
}
</style>
<div id="scroller">
  <div style="height: 800px;">Scroll me to rotate the red box.</div>
</div>
<div class="box"></div>
<button onclick="changeTimeline()">Change Timeline via JS</button>
<script>
function changeTimeline() {
  const scroller = document.getElementById("scroller");
  const newName = "--new-timeline-name";
  scroller.style.setProperty("scroll-timeline-name", newName);
  document.querySelector(".box").style.animationTimeline = newName;
  console.log("Timeline name updated to: " + newName);
}
</script>

Pro Tip

You can use the scroll-timeline shorthand property to define both the name and the axis in a single line. It is much cleaner for your production code and keeps related logic together.

Deep Dive

Think of this property like a radio station's call sign. When you apply a name to a scrollable container, you are broadcasting its scroll position under that name. Any other element on the page can then 'tune in' to that name using the animation-timeline property. Normally, animations run on a wall-clock, meaning they start and end based on time. By using a named scroll timeline, the animation's 'clock' becomes the scrollbar. As the user moves the scrollbar, the animation moves forward or backward. This effectively bridges the gap between layout scrolling and visual motion without needing heavy JavaScript scroll listeners.

Best Practices

Stick to clear, semantic names for your timelines, like --reading-progress or --gallery-scroll. Always verify that the element you are naming actually has overflow set to auto or scroll. If the container doesn't scroll, the timeline is effectively dead air, and your linked animations won't play. Keep names unique within your project to avoid different containers stepping on each others signals.

Common Pitfalls

The biggest hang-up for most developers is forgetting the double dashes at the beginning of the name. Without those dashes, the browser treats it as an invalid keyword and ignores it. Another trap is naming a container but forgetting that the default scroll axis is vertical (block). If you're trying to track a horizontal carousel, you'll need to set the scroll-timeline-axis property to inline as well.

Accessibility

Scroll-linked animations can be disorienting or cause nausea for users with vestibular disorders. Use the prefers-reduced-motion media query to disable or simplify these animations for users who have requested a less movement-heavy experience.

Dev Data Table: scroll-timeline-name property

default none
animatable no
inherited no
experimental no
year_intro 2022
year_standard 2023
js_syntax_1 element.style.scrollTimelineName = '--my-timeline';
js_syntax_2 element.style.setProperty('scroll-timeline-name', '--my-timeline');
js_note When manipulating this in JavaScript, ensure you include the required double dashes for the identifier name.
browsers { "Chrome": 115, "Edge": 115, "Firefox": 114, "Safari": 17, "Opera": 101, "Chrome Android": 115, "Safari on iOS": 17, "Samsung Internet": "23.0", "Opera Mobile": 77 }
results render here...