A Step by Step Guide
Introduction:
In this tutorial, we'll walk through the process of building a dynamic
progress bar using HTML, CSS, and JavaScript. Progress bars are commonly used
in web applications to visualize the completion status of a task or process.
By the end of this tutorial, you'll have a functional progress bar that
updates in real-time based on user input.
![]() |
Figure: Preview (tap to see clearly) |
Prerequisites:
Before diving into this tutorial, you should have a basic understanding of
HTML, CSS, and JavaScript. Familiarity with concepts such as HTML elements,
CSS styling, and JavaScript functions will be beneficial.
Step-by-Step Guide:
- Setting up the HTML structure
- Styling the progress bar with CSS
- Adding interactivity with JavaScript
1. Setting up the HTML structure
Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Progress Bar</title>
</head>
<body>
<div class="container">
<div id="progress-bar">
<p id="percentage">100%</p>
<svg width="200" height="200">
<defs>
<linearGradient id="my-gradient" x1="0%" x2="100%" y1="100%" y2="0%">
<stop offset="0%" stop-color="gold" />
<stop offset="100%" stop-color="red" />
</linearGradient>
</defs>
<circle id="progress-circle" cx="100" cy="100" r="85"></circle>
</svg>
</div>
<input type="number" placeholder="Percentage">
<button onclick="update()">Update</button>
</div>
</body>
</html>
1. HTML Structure:
- Create a new HTML file and add the basic structure with <html>, <head>, and <body> tags.
- Inside the <body> tag, add a <div> element with a class of "container" to hold the progress bar components.
- Inside the container <div>, add another <div> with an id of "progress-bar" to contain the progress bar itself.
- Within the progress bar <div>, add a <p> element with an id of "percentage" to display the progress percentage.
- Add an SVG element with a circle inside to represent the progress visually.
- Include an <input> element of type "number" for the user to input the desired percentage.
- Finally, add a <button> element with an onclick attribute set to a JavaScript function called "update()" to trigger the progress update.
2. Styling the progress bar with CSS
Code:
* {
margin: 0;
padding: 0;
font-family: Arial;
}
body {
background-color: black;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
color: white;
display: flex;
flex-direction: column;
align-items: center;
width: 300px;
}
#progress-bar {
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
font-weight: bold;
font-size: 1.5em;
position: relative;
margin-bottom: 40px;
}
svg {
position: absolute;
top: 0;
left: 0;
}
circle {
fill: none;
stroke: url(#my-gradient);
stroke-width: 30px;
stroke-dasharray: 534;
stroke-linecap: round;
transition: stroke-dashoffset 2s linear;
}
input {
width: 100%;
height: 40px;
border-radius: 20px;
border: none;
text-align: center;
color: #555;
font-size: 1.1em;
margin-bottom: 10px;
}
button {
width: 100%;
height: 40px;
border-radius: 20px;
border: none;
background-color: gold;
color: #555;
font-size: 1.1em;
font-weight: bold;
}
Here's a breakdown of the CSS code provided:
- Universal Reset:
- *: Selects all elements on the page.
- margin: 0; padding: 0;: Resets the margin and padding of all elements to zero.
- font-family: Arial;: Sets the default font family to Arial for all text elements.
- Body Styles:
- background-color: black;: Sets the background color of the body to black.
- display: flex; justify-content: center; align-items: center;: Centers the content vertically and horizontally within the body using flexbox.
- height: 100vh;: Sets the height of the body to 100% of the viewport height.
- Container Styles:
- .container: Styles the container div.
- color: white;: Sets the text color inside the container to white.
- display: flex; flex-direction: column; align-items: center;: Positions the elements inside the container in a column layout and centers them horizontally.
- width: 300px;: Sets the width of the container to 300 pixels.
- Progress Bar Styles:
- #progress-bar: Styles the progress bar container.
- display: flex; justify-content: center; align-items: center;: Centers the progress bar content vertically and horizontally.
- width: 200px; height: 200px;: Sets the width and height of the progress bar container to 200 pixels.
- font-weight: bold; font-size: 1.5em;: Applies bold font weight and increases the font size to 1.5em for the progress percentage display.
- position: relative;: Sets the position of the progress bar container to relative for positioning the SVG element.
- SVG Styles:
- svg: Styles the SVG element inside the progress bar.
- position: absolute; top: 0; left: 0;: Positions the SVG element at the top left corner of the progress bar container.
- Circle Styles:
- circle: Styles the circle element inside the SVG.
- fill: none;: Removes fill color from the circle.
- stroke: url(#my-gradient);: Applies a linear gradient stroke color defined by the my-gradient ID.
- stroke-width: 30px;: Sets the width of the stroke to 30 pixels.
- stroke-dasharray: 534;: Defines the length of the dash pattern for the stroke.
- stroke-linecap: round;: Sets the style of the stroke line cap to round.
- transition: stroke-dashoffset 2s linear;: Adds a transition effect to the stroke-dashoffset property with a duration of 2 seconds and linear easing.
- Input and Button Styles:
- input: Styles the input element.
- button: Styles the button element.
- These styles define the appearance of the input field and button, including width, height, border-radius, border, background color, text color, font size, and font weight.
3. Adding interactivity with JavaScript
Code:
// function for get value from input element entered by user and return it
function getInputValue () {
// get input element
const input_el = document.querySelector ("input");
// get input element value
const input_val = input_el.value;
// return it
return input_val;
}
// function for clear input field
function clearInputField () {
// get input element
const input_el = document.querySelector ("input");
// clear
input_el.value = "";
}
// function for enable or disable button
function disabledButton (bool) {
// get button element
const button_el = document.querySelector ("button");
// set bool for it
button_el.disabled = bool;
// set background color on different state
if (bool) {
button_el.style.backgroundColor = "gray";
}else {
button_el.style.backgroundColor = "gold";
// clear input field
clearInputField ();
}
}
// This is called when the user clicks the button
// and update percentage text and progress bar
function update () {
disabledButton(true);
// get input value from getInputValue function
let input_val = getInputValue ();
// condition for check input_val entered by user
// Number only not empty
if (input_val) {
// change input_val to Integer
input_val = parseInt (input_val);
// change input_val to absolute (e.g. -75 to 75)
input_val = Math.abs(input_val);
// condition for check input_val is greater than 100
if (input_val > 100) {
input_val = 100;
}
}else {
input_val = 0;
}
// calling function
updateProgressBar (input_val);
}
// function for change text in paragraph element
function changeTextInPara (num) {
// get paragraph (para) element (el) by id
const para_el = document.getElementById ("percentage");
// change text in paragraph
para_el.innerText = num + "%";
}
// function for update dash offset value
function updateDashOffset(dashoffset_val) {
// get circle element by it's Id
const circle = document.getElementById('progress-circle');
// set it's transition value to none
circle.style.transition = 'none'; // Disable transition temporarily
// set attribute
circle.setAttribute('stroke-dashoffset', dashoffset_val);
// Trigger reflow to apply immediate changes
void circle.offsetWidth;
// Re-enable transition with empty string (using single quotes)
circle.style.transition = '';
}
// function for update progress bar
function updateProgressBar (percentage) {
// here, calculating the dashoffset value from percentage
const dashoffset_val = Math.round (534 - (534*percentage)/100);
// update dashoffset with dashoffset_val
updateDashOffset (dashoffset_val);
// get paragraph (para) element (el) by id
const para_el = document.getElementById ("percentage");
// get innerText value of para_el
// and remove '%' with replace method
let current_percentage = para_el.innerText.replace ("%", "");
// condition
if (current_percentage < percentage) {
// calculate the interval time for increasePercentage
const interval_time = Math.round (2000/(percentage - current_percentage));
// calling increasePercentage
increasePercentage (current_percentage, percentage, interval_time);
}else if (current_percentage > percentage) {
// calculate the interval time for decreasePercentage
const interval_time = Math.round (2000/(current_percentage - percentage));
// calling decreasePercentage
decreasePercentage (current_percentage, percentage, interval_time);
}else {
disabledButton (false);
}
}
// function for increase percentage
function increasePercentage (current_percentage, percentage, interval_time) {
const my_interval = setInterval ( () => {
changeTextInPara (current_percentage);
current_percentage ++;
if (current_percentage > percentage) {
clearInterval (my_interval);
disabledButton (false);
}
}, interval_time);
}
// function for decrease percentage
function decreasePercentage (current_percentage, percentage, interval_time) {
const my_interval = setInterval ( () => {
changeTextInPara (current_percentage);
current_percentage --;
if (current_percentage < percentage) {
clearInterval (my_interval);
disabledButton (false);
}
}, interval_time);
}
Here's a breakdown of the JavaScript code provided:
- getInputValue Function:
- This function retrieves the value entered by the user in the input field and returns it.
- clearInputField Function:
- This function clears the input field by setting its value to an empty string.
- disabledButton Function:
- This function enables or disables the button based on the boolean parameter passed to it.
- If the button is disabled, its background color is set to gray. Otherwise, it's set to gold.
- If the button is enabled, the input field is also cleared using the clearInputField function.
- update Function:
- This function is called when the user clicks the button.
- It disables the button to prevent multiple clicks while updating the progress bar.
- It retrieves the input value, parses it to an integer, and ensures it's within the range of 0 to 100.
- Then, it calls the updateProgressBar function with the calculated percentage value.
- changeTextInPara Function:
- This function changes the text content of the paragraph element with the specified ID to the provided number followed by a percentage sign.
- updateDashOffset Function:
- This function updates the dash offset value of the SVG circle to visually represent the progress.
- It temporarily disables the transition effect to apply immediate changes, updates the dash offset attribute, triggers a reflow to apply the changes immediately, and then re-enables the transition.
- updateProgressBar Function:
- This function calculates the dash offset value based on the percentage and updates the progress bar.
- It also updates the percentage text displayed on the progress bar and calls either the increasePercentage or decreasePercentage function based on the current and target percentage values.
- increasePercentage and decreasePercentage Functions:
- These functions gradually increase or decrease the percentage displayed on the progress bar to provide a smooth transition effect.
- They update the percentage text and clear the input field when the transition is complete, then re-enable the button.
Conclusion:
Congratulations! You've successfully created a dynamic progress bar using HTML, CSS, and JavaScript. You can now integrate this progress bar into your web projects to provide visual feedback on task completion or process status.
Experiment with different styling options and functionality enhancements to tailor the progress bar to your specific needs.
Thank You:
Thank you for following along with this tutorial. We hope you found it helpful and informative.
If you have any questions or feedback, feel free to leave a comment below.
Comments
Post a Comment