CSS animation-range-end Property

The animation-range-end property specifies the end point of an animation's attachment range along its timeline. It is primarily used in scroll-driven animations to determine exactly where the animation finishes relative to the scroll progress.

selector { animation-range-end: <value>; }
normal Represents the default end of the animation range which is the end of the timeline.
<length-percentage> A specific length or percentage value that defines the end point along the animation timeline.
entry The animation ends when the element has fully entered the scrollport.
exit The animation ends when the element starts to leave the scrollport.
cover The animation ends when the element has completely finished crossing the scrollport.
contain The animation ends when the element has reached the far edge of being contained within the scrollport.
entry-crossing The animation ends when the element finishes crossing the starting edge of the scrollport.
exit-crossing The animation ends when the element finishes crossing the exit edge of the scrollport.

Code Examples

This basic example ensures an image fades in completely by the time it has fully entered the bottom of the viewport.

.scroll-box {
  view-timeline-name: --revealer;
  view-timeline-axis: block;
}

.reveal-image {
  animation: fade-in linear forwards;
  animation-timeline: --revealer;
  animation-range-start: entry 0%;
  animation-range-end: entry 100%;
}

@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

This advanced example uses a scroll timeline to grow a progress bar, with a script showing how to dynamically move the finish line.

<div id="container" style="height: 300vh;">
  <div id="tracker" style="position: fixed; top: 0; width: 0%; height: 10px; background: #ff0000;"></div>
</div>

<style>
#tracker {
  animation: grow-progress linear forwards;
  animation-timeline: scroll();
  /* Animation finishes halfway down the page */
  animation-range-end: 50%;
}

@keyframes grow-progress {
  to { width: 100%; }
}
</style>

<script>
// Dynamically adjust the end point based on user selection
function updateEndRange(val) {
  const tracker = document.getElementById("tracker");
  tracker.style.animationRangeEnd = val + "%";
  console.log("New animation finish line set to: " + val + "%");
}
// Example usage: updateEndRange(75);
</script>

Pro Tip

You can combine a keyword and a percentage to get surgical precision. For example, "exit -20%" will end the animation slightly before the element actually begins to leave the viewport. This is great for ensuring a fade-out animation is fully invisible before the element's container starts to clip.

Deep Dive

Think of your animation like a car trip. If the animation-timeline is the entire highway, animation-range-end is your exit ramp. By default, the animation runs to the very end of the timeline, but this property lets you cut it short. When you use keywords like "exit" or "cover," you are telling the browser to calculate the finish line based on the element's visibility within the scroll container. For example, setting it to "entry 100%" means the animation must be completely finished the moment the element is fully visible at the bottom of the screen. This property works in tandem with animation-range-start to create a specific window of activity. If you provide a percentage without a keyword, it refers to the progress of the entire scroll timeline.

Best Practices

Use the shorthand "animation-range" property to define both start and end points in one line of code to keep your CSS lean. Always test your scroll-driven animations on different screen heights to ensure the "end" point triggers logically for the user. Stick to the "cover" keyword if you want the animation to span the entire journey of the element through the viewport.

Common Pitfalls

A common mistake is setting an end range that occurs before the start range, which results in the animation never running. Another trap is forgetting that this property has no effect on standard time-based animations; it requires a scroll-timeline or view-timeline to be active. Also, be aware that browser support is still growing, so use feature detection.

Accessibility

Animations triggered by scrolling can cause motion sickness for some users. Always wrap your scroll-driven animation logic in a media query for "prefers-reduced-motion: no-preference" so users who find it jarring can opt out. Ensure that the final state of your animation (at the end range) leaves the content in a readable, accessible state.

Dev Data Table: animation-range-end property

default normal
animatable no
inherited no
experimental no
year_intro 2022
year_standard 2023
js_syntax_1 object.style.animationRangeEnd = "cover 100%";
js_syntax_2 object.style.setProperty("animation-range-end", "exit 50%");
js_note When using JavaScript to set this property, ensure the browser supports scroll-driven animations or provide a fallback for standard time-based animations.
browsers { "Chrome": 115, "Edge": 115, "Firefox": 121, "Safari": 17, "Opera": 101, "Chrome Android": 115, "Safari on iOS": 17, "Samsung Internet": 23, "Opera Mobile": 77 }
results render here...