motion · scroll · web-platform
View progress timeline
also called view timeline (css), view() (css), entry and exit range (css), cover and contain (css), animation-range (css)
A scroll timeline measured by one element's passage through the scrollport, with named ranges for entering, being contained, covering, and exiting.
There are two things a scroll can measure, and CSS gives them two different functions.
animation-timeline: scroll() measures the scroller: nought per cent is the top of the container and
one hundred per cent is the bottom, and every element driven by it shares one playhead.
animation-timeline: view() measures one element’s own journey through the scrollport instead, so a
card halfway up the page and a card at the very bottom each get a timeline of their own that starts
when they arrive and finishes when they leave. That is the whole difference, and it is why the same
scroll gesture drives the two completely differently: a
scroll-linked animation reads the scroller’s progress and a view progress
timeline reads the subject’s progress through the viewport, so one number is shared by the page while
the other belongs to a single box.
The ranges are what make it usable, because “the journey” needs naming. cover is the whole overlap:
it begins the instant the element’s leading edge touches the far edge of the scrollport and ends the
instant its trailing edge clears the near one. contain is only the stretch where the element is
wholly inside, which for an element taller than the scrollport inverts into the stretch where the
scrollport is wholly inside the element. entry runs from the start of cover to the start of
contain, and exit from the end of contain to the end of cover, which makes them exactly the
arriving and the leaving. animation-range: entry 0% entry 100% is the everyday fade-up, and the
crossing variants (entry-crossing, exit-crossing) measure against one edge rather than two, which
is what you want when the element is enormous and contain has stopped meaning anything useful.
The other thing to keep it apart from is a scroll-triggered animation, which is a different mechanism wearing the same effect. A trigger watches for a threshold, fires a normal timed animation once, and is finished whether or not the reader keeps scrolling. A view progress timeline never plays: the element’s position is the playhead, so scrolling back up walks the animation backwards through the same frames, and there is nothing to interrupt, replay, or debounce. If the effect should happen once and stay done, a trigger is the honest tool and a timeline will look broken when the reader scrolls back.
Two things bite in practice. The first is that cover only touches nought and one hundred per cent
when the element genuinely crosses both edges: anything already on screen at load starts partway
through its own timeline, and anything short of the far edge never finishes, which is why an entrance
tied to cover can appear pre-faded on the first screen. The entry range plus a
view-timeline-inset to move the trip wire off the exact edge is usually the fix. The second is that
these animations are still animations. They are driven by a gesture rather than by a clock, which
makes them feel direct, but a reader who has asked for less movement has still asked for less
movement, so the declaration belongs behind
prefers-reduced-motion like any other.
Which word?
| If you want | say |
|---|---|
| the animation should track one element, not the whole page | view progress timeline |
| scrolling should start the motion, not steer it | scroll-triggered animation |
Related
See also: Scroll-linked animation