<div id="scroll-progress-1" class="scroll-progress">
	<span class="scroll-progress-percentage"></span>
</div>

<div id="scroll-progress-2" class="scroll-progress"></div>
<main>
	<div id="scroll-progress-3" class="scroll-progress">
		<span class="scroll-progress-percentage"></span>
	</div>
	<div id="scroll-target-1">
		<h1>A Simple Vanilla Scroll Progress Bar/Indicator</h1>
		<p>
			Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer consectetur quam velit, vitae molestie nisl rutrum ac. Vestibulum placerat sem erat, a aliquet nibh scelerisque sit amet. Aliquam fringilla felis in libero egestas mattis. Maecenas non tempor orci. Sed vitae velit ac sapien interdum suscipit condimentum in lorem. Mauris imperdiet id turpis eleifend mattis. Integer interdum metus ac nunc consequat tempus. Fusce sit amet aliquam libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Sed a felis vehicula, fermentum ante in, congue ipsum.
		</p>
		<p>
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Pellentesque et tellus vel turpis ultricies cursus. Sed ac ligula id odio bibendum pretium vitae eu lacus. Pellentesque turpis arcu, porttitor sed nisl imperdiet, aliquam scelerisque sem. Praesent lobortis eget est a interdum. Sed ac risus ante. Praesent vitae condimentum eros, vitae posuere dolor. Quisque iaculis, odio at convallis accumsan, ante mi mattis lectus, vel mollis enim libero at libero. Proin mattis feugiat ante eget sodales. Praesent nulla ipsum, consequat et erat id, vehicula porttitor est. Maecenas ligula felis, interdum at arcu pharetra, dignissim imperdiet odio. Donec finibus pellentesque consectetur. Aliquam dictum volutpat velit, sit amet pellentesque velit ultricies at. Quisque molestie, metus gravida vehicula imperdiet, libero leo consectetur sapien, sed sagittis sapien velit in lectus. Pellentesque euismod sagittis faucibus. Ut dapibus enim dictum vehicula tincidunt.
</p>
<p>
Sed eu fermentum purus. Nulla tincidunt mauris vel odio egestas ullamcorper. In id finibus tellus. Nulla vel accumsan velit. Fusce vel finibus libero. Nam mollis urna ipsum, eu vehicula risus mattis et. Suspendisse potenti. Proin sodales vel libero vel pellentesque. Cras lobortis eros vitae ipsum viverra, nec dapibus augue maximus. Integer convallis tortor ut tellus scelerisque, in tempus neque porta. Donec sollicitudin sapien quis tristique elementum. Fusce scelerisque vulputate venenatis. Fusce a dolor et turpis sodales hendrerit id et sem. Nam vel purus ac nunc fringilla tempor vel sit amet lorem.
</p>
		<p>
			Proin at bibendum ipsum. Mauris gravida, nulla vel tempus sollicitudin, lacus neque placerat risus, vel facilisis ipsum orci quis quam. Etiam condimentum urna venenatis risus pretium mattis. Pellentesque eros enim, mollis vel imperdiet quis, auctor vel quam. Pellentesque in urna nec lorem lacinia tempor. Praesent viverra neque vel dolor cursus ultricies. Vivamus dictum est sem, nec commodo est egestas vel. Maecenas lacus augue, euismod eu mauris at, mollis dictum velit. Quisque placerat velit in quam rhoncus, non aliquam quam facilisis. Aliquam erat volutpat.
		</p>
		<p>
			Vivamus ligula nisl, scelerisque aliquet semper in, posuere quis orci. Integer urna nunc, tempus varius mollis quis, tincidunt quis velit. Mauris sem eros, sodales eget malesuada et, mattis in risus. In dolor est, vulputate vitae rhoncus eget, blandit sed nibh. Vivamus non imperdiet mi. Aliquam tortor justo, posuere eget risus eget, suscipit suscipit tellus. Suspendisse vel accumsan nulla. Sed vel velit efficitur, consequat ex in, condimentum justo. Fusce viverra ligula dui, id accumsan orci eleifend et. Ut vitae tincidunt velit. Vivamus urna mauris, interdum et massa sit amet, volutpat laoreet arcu. Aenean et ipsum eu nisl interdum efficitur. Nullam scelerisque dui euismod aliquet tincidunt. Curabitur placerat enim sit amet viverra finibus.
		</p>
		<p>
			Etiam auctor bibendum dolor. Aliquam et condimentum sapien. Phasellus nisi lectus, lobortis at sodales id, faucibus sed velit. Pellentesque at pharetra velit. In quis bibendum erat. Pellentesque aliquam justo a ultrices dignissim. Morbi lacinia neque non condimentum mollis. Donec sodales dui in leo feugiat facilisis. Nullam volutpat efficitur ex quis ornare. Nulla facilisi.
		</p>
	</div>
	<hr>
	<div id="scroll-target-2">
		<h1>Easy to customize with CSS</h1>
		<p>
			Mauris sit amet tristique urna. Vivamus eget rhoncus turpis. Pellentesque ornare turpis sed odio imperdiet interdum. Ut pulvinar tristique massa vitae luctus. Donec et imperdiet ligula. Suspendisse tristique, tellus nec efficitur consequat, elit tortor laoreet orci, maximus commodo elit mi nec magna. Aliquam egestas lobortis urna. Praesent condimentum augue vitae dui posuere, vitae ultricies velit euismod. Donec suscipit diam ac blandit mattis. Ut a efficitur nulla. Fusce ut augue eu dolor bibendum pellentesque in efficitur nibh. Vestibulum a felis faucibus, malesuada lectus elementum, mollis urna. Nulla mattis vulputate libero vel fringilla. Integer et felis viverra, fermentum ante dictum, euismod risus.
		</p>
		<p>
			Phasellus pretium iaculis turpis, quis ultrices nulla hendrerit eget. Morbi eget feugiat augue, eu ultrices turpis. Vivamus blandit, nibh porttitor gravida vehicula, nunc augue sollicitudin purus, vitae mattis mi orci eu mi. Phasellus efficitur malesuada libero et maximus. Nulla at condimentum turpis. Ut iaculis dapibus magna, sed ultricies lectus pharetra id. Fusce a lacus eu nunc faucibus laoreet. Maecenas et nunc risus. Proin scelerisque pharetra nisl, nec placerat turpis feugiat molestie.
		</p>
		<p>
			Maecenas convallis, dui eget cursus porttitor, odio arcu pharetra ipsum, non egestas quam enim at massa. Sed accumsan ut nulla et efficitur. Vivamus efficitur vel leo sed eleifend. Cras sed leo in metus imperdiet ultricies nec vitae libero. Sed varius justo sit amet massa aliquam, eu gravida enim tincidunt. Ut aliquet placerat leo vitae ultrices. Phasellus varius nisl quis ex mattis, sit amet scelerisque sapien fringilla. Maecenas arcu libero, consectetur quis semper consequat, feugiat a est. Fusce sed neque diam.
		</p>
		<p>
			Nulla facilisi. Cras ornare viverra tortor in mollis. Sed bibendum diam et dictum eleifend. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce libero nunc, venenatis a tortor sed, facilisis vestibulum est. Donec gravida nec dui eu vulputate. Duis dolor lectus, tempus non ligula vitae, sagittis interdum tortor. Suspendisse ac nulla pretium, finibus lorem id, tempus ante. Etiam id posuere nisl, nec dapibus nulla.
		</p>
		<p>
			Cras mi massa, gravida vitae libero quis, sollicitudin maximus diam. Nulla vulputate mattis pulvinar. Proin dignissim lorem vitae efficitur interdum. Duis sed odio neque. Donec id est eu tellus pellentesque pharetra vel vitae ipsum. Proin nec ex non nunc dignissim ornare id sit amet orci. Donec feugiat lectus at dolor ultrices molestie. Nunc ultricies eros tortor, vel vestibulum nulla scelerisque sed. Donec pharetra velit nec sodales rutrum. Praesent ornare tempus erat in efficitur.
		</p>
		<p>
Sed eu fermentum purus. Nulla tincidunt mauris vel odio egestas ullamcorper. In id finibus tellus. Nulla vel accumsan velit. Fusce vel finibus libero. Nam mollis urna ipsum, eu vehicula risus mattis et. Suspendisse potenti. Proin sodales vel libero vel pellentesque. Cras lobortis eros vitae ipsum viverra, nec dapibus augue maximus. Integer convallis tortor ut tellus scelerisque, in tempus neque porta. Donec sollicitudin sapien quis tristique elementum. Fusce scelerisque vulputate venenatis. Fusce a dolor et turpis sodales hendrerit id et sem. Nam vel purus ac nunc fringilla tempor vel sit amet lorem.
</p>
		<p>
			Proin at bibendum ipsum. Mauris gravida, nulla vel tempus sollicitudin, lacus neque placerat risus, vel facilisis ipsum orci quis quam. Etiam condimentum urna venenatis risus pretium mattis. Pellentesque eros enim, mollis vel imperdiet quis, auctor vel quam. Pellentesque in urna nec lorem lacinia tempor. Praesent viverra neque vel dolor cursus ultricies. Vivamus dictum est sem, nec commodo est egestas vel. Maecenas lacus augue, euismod eu mauris at, mollis dictum velit. Quisque placerat velit in quam rhoncus, non aliquam quam facilisis. Aliquam erat volutpat.
		</p>
		<hr>
		<span style="display: flex; align-items: start; justify-content: space-between">By Colin Espinas<span><a href="https://codepen.io/Call_in" target="_blank"><img height="24" width="24" src="https://cdn.jsdelivr.net/npm/simple-icons@v3/icons/codepen.svg" /></a> <a href="https://github.com/ColinEspinas" target="_blank"><img height="24" width="24" src="https://cdn.jsdelivr.net/npm/simple-icons@v3/icons/github.svg" /></a><a href="https://www.buymeacoffee.com/ColinEspinas" target="_blank"><img height="24" width="24" src="https://cdn.jsdelivr.net/npm/simple-icons@v3/icons/buymeacoffee.svg" /></a></span></span>
	</div>
</main>
@import url('https://fonts.googleapis.com/css2?family=Alata&display=swap');

body {
	box-sizing: border-box;
	font-family: 'Alata', sans-serif;
	background-color: #ebecf1;
	color: #1b1c25;
	margin: 0;
	padding: 100px;
	max-width: 800px;
	margin: 0 auto;
}

main {
	position: relative;
	margin-bottom: 100px;
}

p {
	text-align: justify;
}

hr {
	height: 2px;
	width: 100%;
	border: none;
	background-color: #1b1c25;
}

.scroll-progress {
	position: fixed;
	top: 0; 
	left: 0;
	width: 0;
	display: flex;
	min-height: 10px;
	justify-content: flex-end;
	align-item: center;
	background-color: #1b1c25;
	transition: width 200ms ease, opacity 200ms ease;
	z-index: 10;
}

.scroll-progress-percentage {
	display: block;
	padding: 5px 10px;
	color: #ebecf1;
}

#scroll-progress-1 {
	background-color: #e11d74;
	border-radius: 0 5px 5px 0;
}

#scroll-progress-2 {
	background-color: #17b978;
	top: auto;
	bottom: 0;
	border-radius: 0 15px 15px 0;
	transition: width 500ms ease, opacity 200ms ease;
}

#scroll-progress-3 {
	background-color: #00bcd4;
	position: absolute;
	top: 0;
	left: -25px;
	width: 10px;
	min-height: 20px;
	border-radius: 15px;
	transition: height 200ms ease, opacity 200ms ease;
	align-items: flex-end;
	z-index: 9;
}

#scroll-progress-3>.scroll-progress-percentage {
	display: block;
	padding: 0 20px;
	color: #1b1c25;
}
class ScrollProgressBar {
	constructor(selector, root, target, callback) {
		// Get elements from selectors
		this.element = document.querySelector(selector);
		this.root = document.querySelector(root) || document.documentElement;
		this.target = document.querySelector(target);
		this.callback = callback;
		// Set events
		window.addEventListener("scroll", this.computeScroll.bind(this));
		window.addEventListener("resize", this.computeScroll.bind(this));
		// Compute to initialize
		this.computeScroll();
	}
	
	computeScroll() {
		// Compute percentage of scroll
		const scrollPercent = ~~((this.root.scrollTop - this.target.offsetTop - this.target.parentElement.offsetTop) / (this.target.clientHeight - this.root.clientHeight) * 100);
		// Call the callback function with scrollPercent as an argument
		if (this.callback && typeof this.callback === "function") 
			this.callback(scrollPercent);
	}
}


// Create ScrollProgressBar objects:

// For progress bar 1
let progressBar1 = new ScrollProgressBar("#scroll-progress-1", null, "#scroll-target-1", function(scrollPercent) {
	
	// Fade progress bar when below completion height
	if (scrollPercent > 100) 
		this.element.style.opacity = 1 - (scrollPercent - 110) / 40;
	else this.element.style.opacity = 1;
	
	// Affect percentage value to the width and the label of the progress bar
	this.element.style.width = this.element.querySelector("span").innerText = Math.max(0, Math.min(100, scrollPercent)) + "%";
});

// For progress bar 2
let progressBar2 = new ScrollProgressBar("#scroll-progress-2", null, "#scroll-target-2", function(scrollPercent) {
	// Affect percentage value to the width of the progress bar
	this.element.style.width = Math.max(0, Math.min(100, scrollPercent)) + "%";
});

// For progress bar 3
let progressBar3 = new ScrollProgressBar("#scroll-progress-3", null, "main", function(scrollPercent) {
	// Affect percentage value to the width and the label of the progress bar
	this.element.style.height = this.element.querySelector("span").innerText = Math.max(0, Math.min(100, scrollPercent)) + "%";
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.