JSFiddle - React, Tailwind, and code Playground
by NexGenUA
HTML
<div class="other"></div>
<div class="wraper">
<div class='low-content'>
<div id='low-content'>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit libero, quo quibusdam illum deleniti laborum dicta voluptates aut culpa quaerat, vel nihil illo aperiam commodi eveniet facilis ab, fugiat repellat deserunt quia! Maxime error velit similique quod vero voluptatibus sequi nisi officia.</div>
</div>
<div id='large-content'>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto esse possimus delectus nesciunt vel praesentium explicabo, blanditiis nostrum. Vitae aperiam, saepe deleniti quasi delectus ab magnam nostrum, temporibus maxime architecto quia rerum, quos, quaerat consectetur! Quae harum, nostrum iusto numquam accusamus unde ad magni aperiam facere quisquam laudantium. Repellat, quidem.</div>
</div>
<div class="other"></div>
CSS
*{
font-family: "Verdana";
font-size: 30px;
}
.wraper {
display: flex;
}
.low-content {
width: 400px;
height: 1000px;
}
#low-content {
width: 400px;
height: 500px;
background: coral;
}
#large-content{
background: green;
width: 400px;
height: 1000px;
}
.other {
height: 1000px;
width: 800px;
background: yellow;
}
JavaScript
/* сохраняем левый блок */
const lc = document.querySelector('#low-content');
/* сохраняем правый блок */
const child = document.querySelector('#large-content')
/* обрабатываем скролл */
const fixed = () => {
/* сохраняем позицию верхней границы правого блока
от верха окна браузера при каждом скроле */
const positionTop = child.getBoundingClientRect().top
/* сохраняем позицию нижней границы правого блока
от верха окна браузера при каждом скроле */
const positionBottom = child.getBoundingClientRect().bottom
/* если верхняя граница правого блока находится
ниже верхней границы окна браузера то обнуляем стили */
if (positionTop > 0) {
lc.style.position = '';
lc.style.top = '';
}
/* если правый блок своей верхней границей скрылся за верхней границей
окна браузера, то левый блок фиксируем и обнуляем верхний марджин */
if (positionTop <= 0) {
lc.style.position = 'fixed';
lc.style.top = 0;
lc.style.marginTop = '';
}
/* если расстояние нижней границы правого блока от верха окна браузера
стала меньше высоты левого блока, фиксед убераем и добавляем верхний
марджин который равен высоте правого блока - высота левого блока */
if (positionBottom <= lc.offsetHeight) {
lc.style.position = '';
lc.style.marginTop = `${child.offsetHeight - lc.offsetHeight}px`;
}
}
/* вешаем событие и отслеживаем скролл браузера */
document.addEventListener('scroll', fixed)