The CSS animation-timeline property accepts a view() operate which, in flip, returns a timeline of how a lot of a component is seen within the a part of a scroll container that’s viewable (formally often known as a scrollport). In different phrases, relatively than letting an animation run a linear development based mostly on how a lot time has elapsed, view() runs animations based mostly on the visibility of the animated factor inside a scrollport.
I prefer to equate it because the CSS model of JavaScript’s Intersection Observer. We will run an animation on a component as that factor enters and exits the scrollport.
Right here’s an instance:
Fairly neat, proper? Relying on the place a picture is within the scrollable carousel, it goes from small and blurry on the far sides whereas getting bigger and clearer when it hits the middle. Now we have a bit of scroll snapping in there as properly to verify every picture merchandise makes a cease.
It’s not that arduous to do! I’ll present you the way it’s actually the identical outdated animation you’re used to writing in CSS, solely utilized on a view timeline as a substitute of a traditional timeline.
However first, the final format
All I’m making right here is a component I’m calling .carousel:
The weather in .carousel will lay out in a single row, which is a one-liner with flexbox. We’ll additionally be sure that any content material overflowing its area is scrollable:
.carousel {
show: flex;
width: max(480px, 50vw);
overflow-x: auto;
}
And, after all, we’d like objects in it that we will scroll round. A set of picture slides.
So far as styling these objects, every one might be one-third the dimensions of the out there area in order that we see three objects at a time when scrolling:
.carousel {
/* similar as earlier than */
.carousel-slide {
flex-shrink: 0;
width: calc(100% / 3); /* present three at a time */
aspect-ratio: .8;
img {
width: 100%;
}
}
}
Then the scrolling
We’ve already set overflow-x on the .carousel, formally making it our scroll container. We will drop in a bit of scroll snapping to verify we’re solely scrolling one merchandise at a time.
.carousel {
/* similar as earlier than */
scroll-snap-type: x obligatory;
scroll-behavior: easy; /* elective for easy scrolling */
scrollbar-width: none; /* elective to cover the scrollbar */
}
We wish to be sure that the slides are aligned to the middle of the scroll container when snapping into place:
.carousel-slide {
/* and many others. */
scroll-snap-align: heart;
}
Right here’s what we’ve to this point:
Subsequent, the animation
Right here’s the actually cool factor I discussed on the very begin: a view timeline animation is actually the identical factor as another CSS animation you write with keyframes. On this case, we would like keyframes the place the carousel objects are small and blurry firstly and finish, however turn into bigger and clearer proper smack dab in the midst of the animation.
@keyframes slide {
/* from begin to 45%, and to the top (100%) */
45%, 100% {
remodel: scale(0.5);
border-radius: 20px;
filter: blur(6px) brightness(.8);
}
/* center */
50% {
remodel: scale(1);
border-radius: 4px;
filter: none;
}
}
Appears to be like acquainted, proper? That is the type of CSS you’ve been writing ceaselessly! And guess what? We set the animation on the factor we’re animating simply as you usually would as properly:
.carousel-slide {
/* and many others. */
animation: slide;
}
The one distinction is that we would like the animation to run on a timeline based mostly on the factor’s present view() as a substitute of the common timeline. That’s the place the animation-timeline property comes into play:
.carousel-slide {
/* and many others. */
animation: slide;
animation-timeline: view(inline);
}
Now, technically talking, we might slap that timeline straight within the animation shorthand property like another constituent animation property, e.g., animation-name, animation-delay, animation-duration, and many others. However assigning a timeline operate this fashion is just not supported by any browsers but. So, for now, your greatest wager is to declare it by itself. Simply you’ll want to declare it after the animation shorthand, or else chances are you’ll end up inadvertently overriding your view timeline with auto (the default property worth) as a substitute of view().
That completes our demo:
See that? All we’ve actually executed is ready a CSS animation that runs on components. Nonetheless, as a substitute of operating on the default timeline, the animation runs when a component scrolls out and in of view. That’s the distinction between normal and look at timelines.
view() vs. scroll()
However wait! You might or could not know that view() timelines are half of a bigger function set referred to as CSS Scroll-Pushed Animations. And view() is just not the one operate supported by the animation-timeline property. We even have the scroll() operate.
The scroll() operate creates a scroll progress timeline that’s tied to the scroll place of a container, whereas view() creates a view progress timeline that’s based mostly on the visibility of a component inside its container.
Each features are helpful in their very own methods! I usually assume view() is best for item-specific reveal results. So, for instance, if we wish to animate a slide solely as that particular slide scrolls into the scrollport, then the view() operate is the right match. That’s why I’ve centered on it for our carousel instance — we wish to observe a component’s place within the scrollport and run the animation accordingly.
Inset parameter and animation-range
You may additionally be questioning what the heck goes within the parentheses of the view() operate. It’s a operate, in spite of everything, so it should settle for one thing in there, proper?
CSS view() takes two arguments: axis (block, inline, x, and y) and the inset. The inset parameter defines an offset from the scrollport’s edges inside which the animated factor is tracked. The official syntax seems like this:
animation-timeline: view( );
…which is merely a elaborate approach of getting particular with precisely what areas of the scrollport we wish to set off the animation. For some animations, beginning and ending the timeline when factor absolutely enters and exits the scrollport could lower issues off.

That’s no good! We wish every merchandise to totally slide in when it absolutely enters the scrollport, not when it absolutely exits. That’s why all of the objects look so staggered — they’re all at completely different factors within the view timeline.
That’s the place the inset parameter makes an enormous distinction. We might be extra particular about saying we would like every factor to start out animation when it comes up from the underside of the scrollport.
animation: slide-in linear each;
animation-timeline: view(100% 0%);
Ah, a lot significantly better:
The animation-range property works alongside comparable traces.
animation-range: entry; /* similar as: entry 0 entry 100%; */
The animation-range property accepts a slew of different key phrases, together with exit (when the factor leaves the scrollport), cowl (when the factor begins to enter begins to depart the scrollport), and include (when the factor absolutely enters then absolutely leaves the scrollport), amongst others. Geoff has revealed a bunch of notes and examples wanting particularly at every one.
One final carousel instance
Typically, carousels use results like fade in-and-out, scaling, and parallax. Nonetheless, since most CSS properties are animate-able, and even those that aren’t might be tricked into being so utilizing registered CSS properties (like within the case of gradient traces), you’ve gotten the choice to discover extra artistic methods of utilizing view() for carousels.
Right here’s an instance the place an animation of simply the background place creates a pleasant motion in a carousel.


![The AI Search Content material Optimization Guidelines [With Google Sheets]](https://blog.aimactgrow.com/wp-content/uploads/2025/06/ai-search-optimization-checklist-120x86.png)






