Cover image for JavaScript and CSS progress bar

JavaScript and CSS progress bar

frontend_io profile image Jefferson Osagie Iyobosa ・2 min read

I recently created a simple progress bar with vanilla JavaScript and CSS.

It's not really a big deal. But someday when you might need something like this, instead of spending time building again, just remember one exists here already:


Your use case might be different however, but I think same logic may apply.

    <div class="cont">
        <div class="loader">
            <label class="counter">Profile is <span>0%</span> complete</label>

Adding css- there isn't really much here, just some styling and some tweaks with CSS psuedo class.
The darker pulse that follows later after the bar is loaded is fine with the CSS psuedo ::after class

        margin-top: 30px;
        height: 20px;
        width: 100%;
        background: rgba(0, 200, 0, .3);
        border-radius: 50px;
    .cont .loader{
        height: 20px;
        position: relative;
        box-sizing: border-box;
        width: 0%;
        background: rgba(0, 200, 0, .8);
        border-radius: 50px;
        transition: width 1.5s linear
    .cont .loader:before{
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        height: 100%;
        border-radius: 50px;
        width: 100%;
        background: linear-gradient(to  right, rgba(0, 200, 0, .3), rgba(0, 100, 0, .8));
        animation: purge 4s infinite ease-out

    @keyframes purge{
            opacity: 0;
            width: 0%;

            opacity: .5
            opacity: 0;
            width: 100%;
    .cont .loader label{
        font-size: 12px;
        position: absolute;
        right: -10px;
        text-align: center;
        top: -25px;
        font-weight: 600;
        transition: .3s;
    .cont .loader:after{
        content: "";
        position: absolute;
        top: -10px;
        right: 0px;
        height: 50%;
        width: 2px;
        background: rgba(0, 200, 0, .8);
    .cont:hover .loader label{
        transform: scale(1.5);
        transition: .3s;

And lastly our JavaScript

window.addEventListener("load", loadProgress)

  function loadProgress(){

    // Get DOM element
    const target = document.querySelector(".loader")
    const counter = target.querySelector("span");

    // Sample form data
    const details = {
        name: "Jefferson",
        age: 12,
        weight: 70,
        level: 30,
        relationship: "",
        contact: "",
        email: "",
     friends: 459

    function getProgress(board){
        let maxLength = 100;
        // Put them into array to get length of form
        let lengthOfBoard = Object.values(board).length;

        // Get possible mark of each field
        let jumps = maxLength/lengthOfBoard;
        let progress = 0;
        for (let field in board){
            // If field is filled add it's mark to progress
            if (board[field]) {
                progress += jumps
        return progress

    // Utilise value calculated from loader
    function implimentLoad(){
        // Simulate a delay
            let progress = Math.round(getProgress(details))
            counter.innerText = `${progress}% `;
            target.style.width = `${getProgress(details)}% `
        }, 1000)


I hope you find this useful...

Posted on by:

frontend_io profile

Jefferson Osagie Iyobosa


Passionate front-end developer looking forward to learning more ... Looking for work!


markdown guide

Hi Jefferson, nice post! By the way, did you thought about using CSS Variables for setting up width of the progress bar? It would look more modern this times.


Hi Wojciech, i'm sorry i am just responding to this. Was away for long.
Yes, CSS variables, i didn't really think about using it. It is a very simple widget and i didn't want to make it look complex. CSS variables are cool by the way. Thanks for the comment :)