How to make a scroll indicator bar with JS, HTML and CSS easily and explained 🖱️
Tags: webdev, javascript, css, html
Published: 2021-03-23 02:39:30

Chances are you have already ran into sites where there is a bar, usually located in the header, that increase or decrease according to the page scroll. So, that's what this post is about. 

{% codepen https://codepen.io/Leoschmittk/pen/eYBqrPa %}

 
# 🔍  Overview 
 Basically, what we want to do is to check where is the scroll compared to page content size, so if the user have scrolled until the middle of the content, the bar is supposed to fulfill 50%, and so on, always tracking and applying the math to do so.

# HTML
 After fitting the bar in the HTML body, just like the codepen example above, add some content to be able to see some effect when scrolls happen.

```html
<div class='scroll-bar-wrapper'> 
  <div class='scroll-bar'> </div>
</div>
```

# JavaScript 

```javascript
window.addEventListener('scroll',()=> indicateScrollBar())

function indicateScrollBar() {
const distanceFromPageTop = document.body.scrollTop || document.documentElement.scrollTop;

const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;

const scrolled = (distanceFromPageTop / height) * 100;

document.querySelector(".scroll-bar").style.width =  `${scrolled}%`;
 
} 
```

- In .js file, `window.addEventListener('scroll',()=> indicateScrollBar())` tells that  whenever the user happens to scroll down or up in the window, `indicateScrollBar()` is called.
- In this function, we first encounter `distanceFromPageTop`, a variable that will receive either `document.body.scrollTop` or `document.documentElement.scrollTop`. If the first does not exist or the browser doesn't recognize, or it's falsy, the second is reserved to that variable, so explained by the `||` (Logical OR) in the middle of them. Almost all browsers consider the first one, a property that give us a number meaning how far in pixels we are from the top. `document.body.scrollTop` differs from `document.documentElement.scrollTop` just because the latter deals with the whole HTML document, and the first deals with the body itself. In this case, it doesn't affect which is used.

- Another variable, so, is declared: `height`. This one will receive the result of `document.documentElement.scrollHeight - document.documentElement.clientHeight`. But what does exactly this expression mean? 

`document.documentElement.scrollHeight` gives us a number referring to the height of HTML document, the max number that we can get until the scroll stuck in the bottom, the whole content.

`document.documentElement.clientHeight` gives us a number referring to the height of HTML document that we can see, that's viewable.

- `scrolled` is another variable that received the expression `(distanceFromPageTop / height) * 100` which will give us the final number.

- Lastly, we get the bar via DOM, and applies this final number as the width of the bar, not forgetting to add the % signal.


Illustration of the difference between `clientHeight` and `scrollHeight`

 ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y18u93rzwbsh494go6wi.png)

# CSS 

```css 
.scroll-bar-wrapper {
  width: 100%;
  height:10px;
  position:fixed;
  top:0;
  left:0;
  background:#CCCCCC;
}

.scroll-bar { 
  width:0;
  height: inherit;
  background: #8D7ECA;
}

```

Now in .css file, we style the bar. The bar wrapper covers 100% of the screen, also fixed at the top, so even in the scrolls it appears. Moreover, the `.scroll-bar`, the visual bar in itself, receive initially `width:0`, as it will change with the user scrolls. As well, the same height as the wrapper, its father, and the color to make it all visual. 

You can make lots of different styles. This is just a sample with the essence. For instance, you could make the bar as a pseudo-element of `main`, so avoiding HTML directly, just like so: 

{% codepen https://codepen.io/Korbraan/pen/bGgGPbO %}




# ✔️ Windup 

I wish you found it interesting or learn sth. Goodbye! 👋