JSFiddle - React, Tailwind, and code Playground

by rough cheap

HTML

<div id="status"></div>
<div class="obox">
  <div class="vertical">
    Bounding Rect Test.
  </div>
</div>
<div class="obox">
  <div class="vertical">
    Bounding Rect Test.
  </div>
</div>
<div id="target" class="obox">
  <div class="vertical">
    Bounding Rect Test.
  </div>
</div>
<div class="obox">
  <div class="vertical">
    Bounding Rect Test.
  </div>
</div>
<div class="obox">
  <div class="vertical">
    Bounding Rect Test.
  </div>
</div>

CSS

.obox {
  background-color: rgba(40, 40, 190, 255);
  border: 4px solid rgb(29, 29, 120);
  color: white;
  width: 350px;
  height: 350px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  margin-top: 1000px;
  margin-bottom: 1000px;
  box-sizing: border-box;
}
#target {
  background-color: red;
}
#status {
  position: fixed;
  top: 0;
  right: 0;
}

JavaScript

let element;

window.addEventListener('load', (e) => {
  element = document.getElementById('target');
}, false);

document.addEventListener('scroll', (e) => {
  let target = element;
  let rect = target.getBoundingClientRect();
  let vy1 = document.documentElement.scrollTop;
  let vy2 = vy1 + document.documentElement.clientHeight;
  let ty1 = vy1 + target.getBoundingClientRect().top;
  let ty2 = ty1 + target.clientHeight;
  let rate = 0.0;
  let vh = 0;
  if (ty1 > vy2 || vy1 > ty2) {
  	rate = 0.0;
    vh = 0;
  } else if (ty2 <= vy2 && vy1 <= ty1) {
  	rate = 1.0;
    vh = target.clientHeight;
  } else if (ty2 > vy2 && vy2 >= ty1) {
  	rate = (vy2 - ty1) === 0 ? 0.00 : (vy2 - ty1) / target.clientHeight;
    vh = vy2 - ty1;
  } else if (vy1 > ty1 && ty2 >= vy1) {
  	rate = (ty2 - vy1) === 0 ? 0.00 : (ty2 - vy1) / target.clientHeight;
    vh = ty2 - vy1;
  }
  let msg = `vy1: ${vy1}<br>` +
  	`vy2: ${vy2}<br>` +
    `ty1: ${ty1}<br>` +
    `ty2: ${ty2}<br>` +
    `ty2 - vy1: ${ty2 - vy1}<br>` +
    `vy2 - ty1: ${vy2 - ty1}<br>` +
    `rate: ${rate}<br>` +
    `vh: ${vh}`;
  document.getElementById('status').innerHTML = msg;
}, false);