JSFiddle - React, Tailwind, and code Playground
by HDL52
HTML
<body>
<div class="emptybox">empty</div>
<div class="emptybox">empty</div>
<div class="scrollbox">
<div class="scrollbox_container">
<div class="scrollbox_container_card">
<p>card one</p>
</div>
<div class="scrollbox_container_card">
<p>card two</p>
</div>
<div class="scrollbox_container_card">
<p>card three</p>
</div>
</div>
</div>
<div class="emptybox">empty</div>
<div class="emptybox">empty</div>
</body>
CSS
* {
padding: 0;
margin: 0;
font-size: 2vmin;
}
p,
img {
pointer-events: none;
user-select: none;
}
div {
display: flex;
justify-content: center;
align-items: center;
user-select: none;
}
body {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
background-color: #171717;
}
.emptybox {
width: 65rem;
height: 40rem;
background-color: #17f700;
border-radius: 5rem;
margin-bottom: 8rem;
font-family: sans-serif;
font-size: 8rem;
color: #f7f7f7;
font-weight: 900;
text-transform: uppercase;
}
.scrollbox {
justify-content: start;
align-items: start;
width: 100%;
overflow: hidden;
}
.scrollbox_container {
justify-content: start;
height: 100vh;
flex-shrink: 0;
}
.scrollbox_container_card {
position: relative;
width: 65rem;
height: 40rem;
background-color: #f7f7f7;
border-radius: 5rem;
margin-left: 5rem;
flex-shrink: 0;
overflow: hidden;
}
.scrollbox_container_card p {
font-family: sans-serif;
font-size: 6rem;
color: #171717;
font-weight: 900;
text-transform: uppercase;
z-index: 1
}
JavaScript
const scrollbox = {
container: document.querySelector('.scrollbox_container'),
cards: [...document.querySelectorAll('.scrollbox_container_card')],
trigger_distance: 0,
border_distance: 0,
distance: 0,
resize() {
let _scrollbox = document.querySelector('.scrollbox');
_scrollbox.style.height = `${this.container.offsetWidth}px`;
this.trigger_distance = _scrollbox.offsetTop;
this.border_distance = _scrollbox.offsetTop + _scrollbox.offsetHeight - innerHeight;
},
move() {
if (scrollY >= this.trigger_distance && scrollY <= this.border_distance) {
this.distance = scrollY - this.trigger_distance;
this.container.style.transform = `translateY(${this.distance}px)`;
let distance_x = this.distance / (this.border_distance - this.trigger_distance) * (this.container.offsetWidth - innerWidth);
for (let i = 0; i < this.cards.length; i++) {
this.cards[i].style.transform = `translateX(${-distance_x}px)`;
}
}
}
};
scrollbox.resize()
window.addEventListener("resize", () => {
scrollbox.resize()
})
window.addEventListener("scroll", () => {
scrollbox.move()
})