JSFiddle - React, Tailwind, and code Playground

by Jogesh Sharma

HTML

<div id="progressBarContainer">
  <div id="progressBar"></div>
</div>
<p>
  Lorem ipsum dolor, sit amet consectetur adipisicing elit. Aspernatur
  provident eveniet veritatis ipsa id consectetur ab tenetur dolores eaque.
  Temporibus laboriosam cum corporis amet doloremque animi aut ipsa ea a?
</p>
<p>
  Lorem ipsum dolor, sit amet consectetur adipisicing elit. Aspernatur
  provident eveniet veritatis ipsa id consectetur ab tenetur dolores eaque.
  Temporibus laboriosam cum corporis amet doloremque animi aut ipsa ea a?
</p>
<p>
  Lorem ipsum dolor, sit amet consectetur adipisicing elit. Aspernatur
  provident eveniet veritatis ipsa id consectetur ab tenetur dolores eaque.
  Temporibus laboriosam cum corporis amet doloremque animi aut ipsa ea a?
</p>
<p>
  Lorem ipsum dolor, sit amet consectetur adipisicing elit. Aspernatur
  provident eveniet veritatis ipsa id consectetur ab tenetur dolores eaque.
  Temporibus laboriosam cum corporis amet doloremque animi aut ipsa ea a?
</p>
<p>
  Lorem ipsum dolor, sit amet consectetur adipisicing elit. Aspernatur
  provident eveniet veritatis ipsa id consectetur ab tenetur dolores eaque.
  Temporibus laboriosam cum corporis amet doloremque animi aut ipsa ea a?
</p>
<p>
  Lorem ipsum dolor, sit amet consectetur adipisicing elit. Aspernatur
  provident eveniet veritatis ipsa id consectetur ab tenetur dolores eaque.
  Temporibus laboriosam cum corporis amet doloremque animi aut ipsa ea a?
</p>
<p>
  Lorem ipsum dolor, sit amet consectetur adipisicing elit. Aspernatur
  provident eveniet veritatis ipsa id consectetur ab tenetur dolores eaque.
  Temporibus laboriosam cum corporis amet doloremque animi aut ipsa ea a?
</p>

CSS

html {
  overflow: -moz-scrollbars-none;
  scrollbar-width: none;
}

body {
  background: #171414;
  font-family: "Courier New", Courier, monospace;
  color: #ffffff;
  padding: 5% 15%;
}

p {
  font-size: 1.8rem;
}

p:first-of-type {
  margin-top: 60px;
}

::-webkit-scrollbar {
  display: none;
}


#progressBarContainer {
  position: fixed;
  z-index: 10;
  background: rgba(255, 255, 255, 0.05);
}


#progressBar {
  position: absolute;
  will-change: transform, opacity;
  background: linear-gradient(to top, violet, red);
  transform-origin: top center;
  transform: scale(1, 0);
  opacity: 0;
}

#progressBarContainer,
#progressBar {
  top: 0;
  right: 0;
  bottom: 0;
  width: 10px;
}

JavaScript

const progressBarContainer = document.querySelector("#progressBarContainer");
const progressBar = document.querySelector("#progressBar");
let totalPageHeight = document.body.scrollHeight - window.innerHeight;
let debounceResize;

window.addEventListener("scroll", () => {
  let newProgressHeight = window.pageYOffset / totalPageHeight;
  progressBar.style.transform = `scale(1,${newProgressHeight})`;
  progressBar.style.opacity = `${newProgressHeight}`;
}, {
  capture: true,
  passive: true
});

window.addEventListener("resize", () => {
  clearTimeout(debounceResize);
  debounceResize = setTimeout(() => {
    totalPageHeight = document.body.scrollHeight - window.innerHeight;
  }, 250);
});

progressBarContainer.addEventListener("click", (e) => {
  let newPageScroll = e.clientY / progressBarContainer.offsetHeight * totalPageHeight;
  window.scrollTo({
    top: newPageScroll,
    behavior: 'smooth'
  });
});