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