<div class="container">
  <section data-bgcolor="#bcb8ad" data-textcolor="#032f35">
      <h1 data-scroll data-scroll-speed="1"><span>Horizontal</span> <span>scroll</span> <span>section</span></h1>
      <p data-scroll data-scroll-speed="2" data-scroll-delay="0.2">With WAAPI + ScrollTimeline</p>


  <section id="sectionPin">
    <div class="pin-wrap">
      <h2>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</h2>
      <img src="https://images.pexels.com/photos/5207262/pexels-photo-5207262.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=900" alt="">
      <img src="https://images.pexels.com/photos/3371358/pexels-photo-3371358.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=900" alt="">
      <img src="https://images.pexels.com/photos/3618545/pexels-photo-3618545.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=900" alt="">

  <section data-bgcolor="#e3857a" data-textcolor="#f1dba7"><img src="https://images.pexels.com/photos/4791474/pexels-photo-4791474.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" alt="">
    <h2 data-scroll data-scroll-speed="1" class="credit"><a href="https://twitter.com/bramus" target="_top" rel="noreferrer noopener">Made by Bramus</a></h2>

<div class="warning">⚠️ Your browser does not support CSS Scroll-Linked Animations, so this demo won't work. If you're feeling adventurous use Chrome 89 with “Experimental Web Platform Features” enabled. Alternatively you can <a href="https://twitter.com/bramus/status/1356589270379724802" target="_top">watch a recording of this demo in action</a> or <a href="https://codepen.io/cameronknight/pen/qBNvrRQ" target="_top" rel="noreferrer noopener">check out a JS version this demo was based upon</a>.</div>
  This is a JS based version of https://codepen.io/bramus/pen/QWGbOBQ
  It uses polyfills for css-typed-om and scroll-timeline

  While it has some bugs on its own (it's not performant), it does render
  the scroll timeline correctly. See bug 1 in CSS version for a description.

/* Right below is the original CSS from https://codepen.io/cameronknight/pen/qBNvrRQ
 * Scroll down to see the extra CSS Additions to implement is using CSS @scroll-timeline
:root {
  --text-color: #111;
  --bg-color: #b9b3a9;

html {
  max-width: 100vw;

body {
  font-family: termina, sans-serif;
  color: var(--text-color);
  background: var(--bg-color);
  transition: 0.3s ease-out;
  overflow-x: hidden;
  max-width: 100vw;
  width: 100%;
  overscroll-behavior: none;

section {
  min-height: 100vh;
  width: 100%;
  max-width: 100vw;
  overflow-x: hidden;
  position: relative;

section:not(#sectionPin) {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-gap: 2rem;
  padding: 50px 10vw;
  margin: auto;
  place-items: center;

img {
  height: 80vh;
  width: auto;
  object-fit: cover;

h1 {
  font-size: clamp(1.5rem, 16vw + 0.5rem, 5rem);
  line-height: 1;
  font-weight: 800;
  margin-bottom: 1rem;
  position: absolute;
  top: 10vw;
  left: 10vw;
  z-index: 4;
  overflow-wrap: break-word;
  hyphens: auto;

  @media (max-width: 768px) {
    font-size: clamp(1.5rem, 5vw + 0.5rem, 5rem);

  span {
    display: block;

h2 {
  font-size: 2rem;
  max-width: 400px;

.credit {
  font-family: Termina, sans-serif;
  a {
    color: var(--text-color);

* {
  box-sizing: border-box;

#sectionPin {
  height: 100vh;
  overflow: hidden;
  display: flex;
  left: 0;
  background: var(--text-color);
  color: var(--bg-color);

.pin-wrap {
  height: 100vh;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding: 50px 10vw;

  & > * {
    min-width: 60vw;
    padding: 0 5vw;

p {
  position: absolute;
  bottom: 10vw;
  right: 10vw;
  width: 200px;
  line-height: 1.5;

/* CSS Additions by Bramus */

/* Show warning for older browser */
.warning {
  position: fixed;
  top: 1em;
  right: 1em;
  left: 1em;
	padding: 1em;
	border: 1px solid black;
  z-index: 9999;
  text-align: center;
  color: black;
  background: rgba(255 255 225 / 0.9);
  display: none;

.warning a {
  color: blue;
View Compiled
// 💡 Looking for a pure CSS Version? ~> https://codepen.io/bramus/pen/QWGbOBQ

// Polyfill for browsers with no Scroll-Timeline support
import 'https://rawcdn.githack.com/flackr/scroll-timeline/94866999efe41b3ccba846be7ed37c9313dd880e/dist/scroll-timeline.js';

const $sectionPin = document.querySelector("#sectionPin");
const $slidingContent = document.querySelector(".pin-wrap");

const sectionHeightInVh = 500; // 👈 The scrolling distance over which the horizontal section should slide across

// Adjust wrapper
// - Change height so that we have room to scroll in
// - Add fix to make position: sticky work
$sectionPin.style.height = `${sectionHeightInVh}vh`;
$sectionPin.style.overflow = `visible`;

// Adjust content
// - Make it stick to the top
$slidingContent.style.position = "sticky";
$slidingContent.style.top = 0;

new Animation(
  new KeyframeEffect(
      transform: ["translateX(0)", `translateX(calc(-100% + 100vw))`]
    { duration: 1, fill: "both" }
  new ScrollTimeline({
    scrollSource: document.documentElement,
    timeRange: 1,
    fill: "both",
    scrollOffsets: [
      { target: $sectionPin, edge: "start", threshold: 1 },
      { target: $sectionPin, edge: "end", threshold: 1 }

External CSS

  1. https://use.typekit.net/skn8ash.css
  2. https://cdn.jsdelivr.net/npm/locomotive-scroll@3.5.4/dist/locomotive-scroll.css

External JavaScript

This Pen doesn't use any external JavaScript resources.