Simple Scroll Indicator

July 16, 2019

3 min read

Today we are going to build a simple scroll indicator using CSS and Javascript. For you who don’t know, a scroll indicator in the horizontal line on top of our page that fills based on where we are vertically on the page. Each page has different height so evidently we have some math to do. (not really).

Prerequisites:

  • Basic knowledge of HTML, CSS and Javascript.

Goals:

  • We will have an understanding on how to calculate where we are vertically on the page.

Our markup will look something like this.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<link rel="stylesheet" href="style.css" />
	<title>Scroll side</title>
</head>
 
<body>
	<nav>
		<div class="load"></div>
	</nav>
    <section>
	    <h2>Post</h2>
	    <p>. . .</p>	
    </section>
</body>
</html>

We have a nav element and a div with a class of ‘load’ inside it. This will serve as our scroll indicator. We also have some content to scroll through. And some styling as well.

body {
	margin: 0;
	font-family: sans-serif;
	background: #f8f8f8;
}

nav {
	height: 50px;
	background: #444444;
	width: 100%;
	position: fixed;
	top: 0;
	left: 0;
}

.load {
	background: #ffa500;
	position: absolute;
	left: 0;
	bottom: -3px;
	height: 3px;
	transition: .4s;
}


section {
	max-width: 900px;
	margin: 0 auto;
	padding: 40px 0;
}

section h2 {
	font-size: 2.5rem;
}

section p {
	font-size: .9rem;
	line-height: 1.71;
}

Some terms to understand before we go ahead with this.

scrollY

Property of the window interface. Returns the number in pixels that the document is currently scrolled vertically. For IE support better use pageYOffset. But come on. Do you want to be that person?

scrollHeight

Measures the height of an element including what is not visible on the screen due to overflow.

clientHeight

Measures the inner height of an element in pixels. Includes padding if present.

So the formula is

From the total height of the entire page (scrollHeight) we will subtract the height of our current viewport (clientHeight). Take the current scrollpoint(scrollY) and divide it by the previous sum.

scrollY / ( scrollHeight – clientHeight )

This will return a decimal. We will round it and turn it into a percentage.

Now let’s fill up our javascript file.

First we declare our variable that grabs the element from the DOM. Then we pass a function to our window object. Each time you scroll up or down the function will be triggered.

const loadbar = document.querySelector('.load');
 
window.addEventListener('scroll', scrollMe);
 
function scrollMe() {
 
}

Since we want to make our calculations all the time, the logic we made before will be placed here

const loadbar = document.querySelector('.load');
 
window.addEventListener('scroll', scrollMe);
 
function scrollMe() {
	let scrollTop = window.scrollY;
	let docHeight = document.documentElement.scrollHeight;
	let clientHeight = document.documentElement.clientHeight;
	let scrollPercent = (scrollTop) / (docHeight - clientHeight);
	let scrollPercentRounded = Math.round(scrollPercent * 100);
 
	loadbar.style.width = scrollPercentRounded + 'vw';
}

Note that previously we didn’t give a width to our div with a class of load.

We are going to do that here

In the first three lines we are setting our variables. In the fourth we are doing the actual calculation and in the fifth we are rounding it. Now scrollPercentRounded will give us a number from 0 to 100 no matter what height we have on our page. In the last line we will pass scrollPercentRounded as width to our load div in our nav. That’s it. Now you know how to control elements behavior with scroll. You can get crazy with this and experiment.

View Demo

Here are a couple more examples. One with linear-gradient and another with box-shadow


Written by John Raptis.
In love with JavaScript, React and programming fundamentals in general.
Follow me on Twitter

© 2020, John Raptis