Version selector

This demo has several versions:

  1. Single set of keyframes
  2. Multiple animations
  3. Single animation with offset info
  4. Multiple animations

About this demo

This demo shows a contact list where the list entries are animated. As a list entry enters the scrollport from the bottom it slides+fades in, and as it exits the scrollport at the top it slides+fades out.

The Code / Explanation

The position of each list item is tracked using a ViewTimeline.

document.querySelectorAll('#list-view li').forEach($li => {

	// Create a ViewTimeline to track the li in its scroller.
	const timeline = new ViewTimeline({
		subject: $li,
		axis: 'block',


This ViewTimeline is used as the timeline for both animations. However, the animate-in animation is attached to the entry range, and the animate-out animation to the exit range of the timeline.

Leveraging the offset option, it’s possible to construct 1 set of keyframes with range information included.

	{ opacity: 0, transform: 'translateY(100%)', offset: 'entry 0%' },
	{ opacity: 1, transform: 'translateY(0)', offset: 'entry 100%' },
	{ opacity: 1, transform: 'translateY(0)', offset: 'exit 0%' },
	{ opacity: 0, transform: 'translateY(-100%)', offset: 'exit 100%' },
], {
	fill: 'both',

Be sure to compare this syntax to the one that uses multiple animations.

⚠️ Your browser does not support Scroll-driven Animations. Please use Chrome 115 or newer.