Version selector

This demo has several versions:

  1. CSS scroll-timeline
  2. JavaScript WAAPI + ScrollTimeline

About this demo

This demos sports section that scrolls horizontally as you scroll down.

Original demo by Cameron Knight:

The Code

<section id="sectionPin">
	<div class="pin-wrap-sticky">
		<div class="pin-wrap">…</div>
@keyframes move {
	to {
		/* Move horizontally so that right edge is aligned against the viewport */
		transform: translateX(calc(-100% + 100vw));

#sectionPin {
	/* Stretch it out, so that we create room for the horizontal scroll animation */
	height: 500vh;
	overflow: visible; /* To make position sticky work … */

	view-timeline-name: --section-pin-tl;
	view-timeline-axis: block;

.pin-wrap-sticky {
	/* Stick to Top */
	height: 100vh;
	width: 100vw;
	position: sticky;
	top: 0;

	width: 100vw;
	overflow-x: hidden;

.pin-wrap {
	height: 100vh;
	width: 250vmax;

	/* Hook animation */
	will-change: transform;
	animation: linear move forwards;

	/* Link animation to view-timeline */
	animation-timeline: --section-pin-tl;
	animation-range: contain 0% contain 100%;


By stretching out #sectionPin to a height of 500vh, more scroll estate is created. A ViewTimeline is attached to that element, tracking it as it crosses the scrollport.

The intermediary element .pin-wrap-sticky is made sticky, and it’s the .pin-wrap that gets animated on the ViewTimeline.

The start position of the horizontal strip .pin-wrap is at 0,0 within its parent. Its end position is a horizontal translation of -100% to which the viewport width is added. If the viewport width were not taken into account, the element would be entirely out of view.

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

Horizontal scroll section

With CSS view-timeline

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Created by Bramus.

Adapted from the original by Cameron Knight.