React On Page Scroll Progress Bar with Web API Tutorial

Last updated on by Digamber
Do you want to display a progress bar on page scroll in React application? Well, then you are at the right place. We are going to build a progress bar only using pure JavaScript and CSS in a React 16+ application.

React Progress Bar

Today, In this tutorial i am going to show you how you can create a progress bar which can show how much have you scrolled on a web page.

Our goal is to create such a progress indicator which works back and forth on scroll very smoothly. The progress bar we are going to build won’t require any third-party package; instead, we will use some of the standard Web APIs:

  • scrollTop
  • scrollHeight
  • clientHeight

Let’s get started.

Create React App

To show on page scroll progress bar demo, first, we need to install the React app. Although, If you have already installed the React app, then you can skip this step.

npx create-react-app react-page-scroll-progressbar

Get into the project folder.

cd react-page-scroll-progressbar

Run the app.

npm start

Make The Component Ready

This is the basic configuration of an essential React component, and we imported the React library from React the folder at the top of the template.

We initialized the component and set the constructor, also defined the initial scroll state to 0.

import React from 'react';

class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      scroll: 0
    };
  }

}

export default App;

How To Create a Scroll Indicator in React

Let’s add the following method inside the React component, and we are about to understand what is going on in here.

progressBar = () => {
  const scrollTotal = document.documentElement.scrollTop;
  const heightWin = document.documentElement.scrollHeight - document.documentElement.clientHeight;
  const scroll = `${scrollTotal / heightWin * 100}%`;

  this.setState({
    scroll: scroll
  });
};

The progressBar() function handles the progress of a progress indicator when the user triggers the scroll event in a react app.

We used the scrollTop web API, and this API is mostly used to get or set the number of pixels that an element content is vertically scrolled.

An element’s scrollTop value is an estimation of the distance from the element’s top to its topmost visible content. Moreover, if an element’s content does not create a vertical scrollbar, then its scrollTop value must be around 0.

To calculate the window height we put a basic formula, in this simple formula we are deducting scrollHeight from clientHeight.

Next, we put the simple logic scrollTotal / heightWin * 100 to calculate the scrolled pixels and set the progress bar state.

scrollHeight: The scrollHeight is a read-only property, and It is a measurement of the height of an element’s content, including content not visible on the screen because of the overflow.

clientHeight: The clientHeight is also a read-only property and by default is zero for the elements with no CSS or inline layout boxes; otherwise, it’s the inner height of an element in pixels. It includes padding but excludes borders, margins, and horizontal scrollbars.

Next, bind the progressBar() function to the componentDidMount and componentWillUnmount React lifecycle hooks.

componentDidMount() {
  window.addEventListener("scroll", this.progressBar);
}

componentWillUnmount() {
  window.removeEventListener("scroll", this.progressBar);
}

Style React Progress Bar

To style progress indicator we need to define the following classes inside the render() function. Our progress bar will have following CSS styling.

const progressMainWrapper = {
  background: "rgba(255, 255, 255, 0.14)",
  height: "15px",
  position: "fixed",
  top: 0,
  left: 0,
  zIndex: 101,
  width: "100%"
};

const progressMainStyle = {
  height: "15px",
  background: "#00cc83",
  width: this.state.scroll
};

The Progress Bar

To display the progress bar on page scroll, we have to define the HTML divs and apply the following styling.

return (
  <div className="progress-bar" style={progressMainWrapper}>
    <div style={progressMainStyle} />
  </div>
);

The Final Code

Open the App.js file here. You can check out the final code for the on-page scroll progress bar example.

import React from 'react';

class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      scroll: 0
    };
  }

  componentDidMount() {
    window.addEventListener("scroll", this.progressBar);
  }

  componentWillUnmount() {
    window.removeEventListener("scroll", this.progressBar);
  }

  progressBar = () => {
    const scrollTotal = document.documentElement.scrollTop;
    const heightWin = document.documentElement.scrollHeight - document.documentElement.clientHeight;
    const scroll = `${scrollTotal / heightWin * 100}%`;

    this.setState({
      scroll: scroll
    });
  };

  render() {
    const progressMainWrapper = {
      background: "rgba(255, 255, 255, 0.14)",
      height: "15px",
      position: "fixed",
      top: 0,
      left: 0,
      zIndex: 101,
      width: "100%"
    };

    const progressMainStyle = {
      height: "15px",
      background: "#00cc83",
      width: this.state.scroll
    };

    return (
        <div className="progress-bar" style={progressMainWrapper}>
          <div style={progressMainStyle} />
        </div>
    );
  }
}

export default App;

Now, if you check on the browser, you will see on top of the web page a progress bar that displays the progress of a page scroll back and forth.

You can get the full code of this tutorial on this Git repo.