<pre class="debug"></pre>
<div class="box" id="box_1">1</div>
<div class="box" id="box_2">2</div>
<div class="box" id="box_3">3</div>
<div class="box" id="box_4">4</div>
<div class="box" id="box_5">5</div>
<div class="box" id="box_6">6</div>
<div class="box" id="box_7">7</div>
<div class="box" id="box_8">8</div>
<div class="box" id="box_9">9</div>
<div class="box" id="box_10">10</div>
body {
  margin: 0;
}

.debug {
  position: fixed;
  top: 0;
  right: 0;
  margin: 0;
  padding: 10px;
  background: #000000;
  color: #ffffff;
}

.box {
  padding: 50px;
  margin: 50px;
  font: 200px 'Segoe UI', Arial, Helvetica, sans-serif;
  background: #dddddd;
  color: rgba(0, 0, 0, 0.5);
}
const debug = document.querySelector('.debug');
const boxes = document.querySelectorAll('.box');

const displayed = {};

function scrollTracking(entries) {
  for (const entry of entries) {
    displayed[entry.target.id] = entry.intersectionRatio >= 0.2;
  }
  
  debug.textContent = Object
    .entries(displayed)
    .filter(([id, inViewport]) => inViewport)
    .map(([id, inViewport]) => id)
    .join('\n');
}

const observer = new IntersectionObserver(scrollTracking, {
  threshold: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
});

boxes.forEach(element => observer.observe(element));

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.