To create a progressbar visualization with css you need 2 div elements, one progressbar track and a progress handle.

In the above figure, 1 is the track and 2 is the handle.

jsx

We’ll add two above mentioned div’s and a a couple of buttons which we’ll click to fill the progressbar.

<div className="App">
    <div className="track">
        <div className="handle" />
    </div>
</div>

Adding css

Let’s add the basic styles to the above jsx elements.

.track{
    width: 300px;
    height: 20px;
    border: 2px solid #5592a6;
    border-radius: 20px;
}
.handle{
    background: #cbce42;
    height: 20px;
    transition: 1s all;
    border-radius: 10px;
}

Set the progress

The width of the handle defines the progress here. So as the width value increases, progressbar will be filled. To demonstrate I have added two buttons which will make the width 50% and 100% respectively.

<div className="App">
    <div className="track">
        <div className="handle" />
    </div>
    <div className="buttonsWrapper">
        <button>Fill Half</button>
        <button>Fill Completely</button>
    </div>
</div>

I will add some basic styling to the buttons.

.buttonsWrapper{
    margin-top: 20px;
    button{
        margin-right: 10px;
        padding: 8px 16px;
        font-size: 15px;
    }
}

Now we need a state variable to define the handle width.

const [width, setWidth] = useState('0%')

Next we will add this width state to the dom element and the functionality of the buttons.

<div className="App">
    <div className="track">
        <div className="handle" style={{ width }} />
    </div>
    <div className="buttonsWrapper">
        <button onClick={() => setWidth('50%')} >Fill Half</button>
        <button onClick={() => setWidth('100%')} >Fill Completely</button>
    </div>
</div>

At this point you can see the desired progress in our progressbar when the buttons are clicked. Also if you want this progressbar on any project where you know the progress value, you can simply apply that variable to the handle element’s width.

For example, if you want to use this progressbar to indicate the progress of a file upload you can convert the progress value returned by the uploader to a percentage value and then feed it as the width value of the handle element.

Finishing up

Lastly let’s add the animation to the progressbar which will slowly fill the progress. Please note that this step will be required only when you are using this progressbar as a loader, not as a real progress indicator. In a real progress indicator ( Eg: file uploader, volume indicator, network strength bar etc) you don’t need an animation as you’ll be feeding the percentage directly to the element’s width which will make the progressbar look animated automatically.

.handle {
    transition: 0.5s width;
}

Summary

The finished working code is available in the following codesandbox link.
https://codesandbox.io/s/progressbar-39fm9?file=/src/App.js

Happy styling!