Version selector

This demo has several versions:

  1. CSS using scroll-timeline
  2. CSS using view-timeline

About this demo

This demo features a header bar that shrinks as you scroll down. Simultaneously, the contents of the header bar also shrink and adjust position. Furthermore, a shadow is also added to the header as it is shrinking.

The Code + Explanation

Each element that needs to be animated – the title, the header itself, the background image, etc. – has its own animation attached.

@keyframes adjust-info {
	to {
		grid-template-columns: 4em 1fr;
		gap: 1rem;
		height: 4.75rem;
@keyframes shrink-name {
	to { font-size: 1.5rem; }
@keyframes add-shadow {
	to { box-shadow: 0 5px 5px -3px rgba(0,0,0,.26); }
@keyframes move-button {
	to { translate: 0% 40%; }
@keyframes move-and-fade-background {
	to {
		translate: 0% -5%;
		scale: 0.96;
		opacity: 0.3;

.info {
	animation: adjust-info linear both;
.info h2 {
	animation: shrink-name linear both;
header {
	animation: add-shadow linear both;
#button-edit  {
	animation: move-button linear both;
.bg  {
	animation: move-and-fade-background linear both;

All of these animations are hooked onto a View Timeline that tracks the <main> element. It’s scope is hoisted up to the body using timeline-scope. That way, any child of body can access the timeline.

body {
	timeline-scope: --main;
main {
	view-timeline: --main;
.info, h2, header, #button-edit, .bg {
	animation-timeline: --main;
	animation-range: exit-crossing -11rem exit-crossing 0;

The animation-range is set to a fixed distance measured from the exit-crossing segment. They start as soon as main is 11rem from the top edge and have finished by the time the main is exactly at the top edge.


Bramus Van Damme

  • Developer Relations Engineer
  • bramus
  • he/him

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

⚠️ Your browser does not support timeline-scope. Please use Chrome 116 or newer.