DEV Community

Cover image for JavaScript and CSS progress bar
Jefferson Osagie Iyobosa
Jefferson Osagie Iyobosa

Posted on

JavaScript and CSS progress bar

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:

https://frontend-io.github.io/Vanilla-JS-and-CSS-progress-bar/

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>
        </div>
    </div>

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

    .cont{
        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{
        0%{
            opacity: 0;
            width: 0%;

        }
        50%{
            opacity: .5
        }
        100%{
            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
        setTimeout(()=>{
            let progress = Math.round(getProgress(details))
            counter.innerText = `${progress}% `;
            target.style.width = `${getProgress(details)}% `
        }, 1000)

    }
    implimentLoad()
  }


I hope you find this useful...

Top comments (2)

Collapse
 
wojciech_space profile image
Wojciech Wernicki

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.

Collapse
 
frontend_io profile image
Jefferson Osagie Iyobosa

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 :)