<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.