<div class="grid">
  <div class="column">
    <img src="https://picsum.photos/500/700?random=1-1" alt="">
    <img src="https://picsum.photos/500/700?random=1-2" alt="">
    <img src="https://picsum.photos/500/700?random=1-3" alt="">
    <img src="https://picsum.photos/500/700?random=1-4" alt="">

  </div>
  <div class="column">
    <img src="https://picsum.photos/500/700?random=2-1" alt="">
    <img src="https://picsum.photos/500/700?random=2-2" alt="">
    <img src="https://picsum.photos/500/700?random=2-3" alt="">
    <img src="https://picsum.photos/500/700?random=2-4" alt="">
    <img src="https://picsum.photos/500/700?random=2-5" alt="">
    <img src="https://picsum.photos/500/700?random=2-6" alt="">
    <img src="https://picsum.photos/500/700?random=2-7" alt="">
  </div>
  <div class="column">
    <img src="https://picsum.photos/500/700?random=3-1" alt="">
    <img src="https://picsum.photos/500/700?random=3-2" alt="">
    <img src="https://picsum.photos/500/700?random=3-3" alt="">
    <img src="https://picsum.photos/500/700?random=3-4" alt="">
    <img src="https://picsum.photos/500/700?random=3-5" alt="">
    <img src="https://picsum.photos/500/700?random=3-6" alt="">
    <img src="https://picsum.photos/500/700?random=3-7" alt="">
  </div>
  <div class="column">
    <img src="https://picsum.photos/500/700?random=4-1" alt="">
    <img src="https://picsum.photos/500/700?random=4-2" alt="">
    <img src="https://picsum.photos/500/700?random=4-3" alt="">
    <img src="https://picsum.photos/500/700?random=4-4" alt="">
    <img src="https://picsum.photos/500/700?random=4-5" alt="">
    <img src="https://picsum.photos/500/700?random=4-6" alt="">
    <img src="https://picsum.photos/500/700?random=4-7" alt="">
  </div>
  <div class="column">
    <img src="https://picsum.photos/500/700?random=5-1" alt="">
    <img src="https://picsum.photos/500/700?random=5-2" alt="">
    <img src="https://picsum.photos/500/700?random=5-3" alt="">
    <img src="https://picsum.photos/500/700?random=5-4" alt="">
  </div>
</div>
@import "https://unpkg.com/normalize.css";

*,
*:after,
*:before {
	box-sizing: border-box;
}

:root {
	--gap: 1rem;
	--card-width: clamp(280px, 20vw, 100vw);
	--card-aspect-ratio: 5 / 7;
	--card-height: calc(var(--card-width) * (7 / 5));
}

body {
	display: grid;
	place-items: center;
	font-family:  'Google Sans', sans-serif, system-ui;
	overflow-x: hidden;
	justify-content: center;
	min-height: 100vh;
}

.grid {
	display: grid;
	justify-content: center;
	grid-template-columns: repeat(5, var(--card-width));
	gap: 1rem;
  /* overflow: hidden shouldn't break this? */
  overflow: hidden;
}

.grid-wrapper {
	/* overflow: hidden; */
}

.column {
	display: grid;
	gap: 1rem;
  align-content: start;
}

.column:not(:nth-of-type(3)) {
	animation: scale 1s linear both;
	animation-timeline: scroll(root);
}

/* The distance is the number of cards minus 100vh */
.column:is(:nth-of-type(2), :nth-of-type(4)) {
	--origin: calc(var(--gap) * -1);
	--destination: calc(var(--card-height) * 1.5 + var(--gap));
}
.column:is(:nth-of-type(1), :nth-of-type(5)) {
	--origin: calc(var(--gap) * -2);
	--destination: calc(var(--card-height) * 3.4 + var(--gap));
}

@keyframes scale {
	0% {
		transform: translateY(var(--origin, 0%));
	}
	100% {
		transform: translateY(var(--destination, -50%));
	}
}

img {
	max-width: 100%;
	border: 0;
	padding: 0;
	max-height: 100%;
	width: 100%;
	aspect-ratio: 5 / 7;
	background: hsl(0 0% 80%);
}
// There is a polyfill at work here.
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://rawcdn.githack.com/flackr/scroll-timeline/1a559d8c701b5f10506b117f4b810310ae6c9e55/dist/scroll-timeline.js