JSFiddle - React, Tailwind, and code Playground

by Joe Pea

HTML

<div class="wrapper">
  <div class="inner">
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
   large div<p/><p /><p /><p />
 ...

CSS

.wrapper {
  /*for reference*/
  border: 3px solid green;
}

.inner {
  width: 100px;
  background: pink;
  
  /*so you can see when you reached the bottom*/
  border-bottom: 10px solid teal; 
}

* {
  box-sizing: border-box;
}

body, html {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
  overflow: scroll;
}

body {
  padding: 10px;
  width: calc(100% / var(--scale));
  height: calc(100% / var(--scale));
  transform-origin: top left;
  transform: scale(var(--scale));
}

JavaScript

const inner = document.querySelector('.inner')
const wrapper = document.querySelector('.wrapper')
const body = document.body
const scale = 4

document.body.style.setProperty('--scale', scale)

body.addEventListener('scroll', () => {
  // on scroll, translate the scrolled object to account for scale,
  // so that it moves at the same speed as a finger on the screen
  // (or same speed as we're used to scrolling with the mouse or touchpad).
  inner.style.transform = `translateY( calc( ${body.scrollTop}px * ( 1 - 1 / ${scale} ) ) )`
})