How to Make a Progress Bar in HTML and CSS

Updated · 6 min read · By

A progress bar is two boxes: an outer track and an inner fill whose width is the percentage. This tutorial builds one step by step, makes it accessible, and adds a few lines of JavaScript to animate it.

HTML and CSS code for a progress bar with a green fill at 65 percent
Prefer a visual editor? The progress bar generator builds the code for you.

The complete code

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Progress Bar</title>
  <style>
    body { font-family: Arial, sans-serif; max-width: 500px; margin: 60px auto; padding: 0 16px; }
    .progress {
      height: 22px;
      background: #e0e0e0;     /* the empty track */
      border-radius: 11px;
      overflow: hidden;         /* keeps the fill inside the rounded corners */
    }
    .progress-fill {
      width: 0%;                /* JavaScript changes this */
      height: 100%;
      background: #00c853;
      color: #fff;
      font: bold 12px/22px Arial, sans-serif;
      text-align: center;
      transition: width 0.4s ease;   /* smooth movement */
    }
  </style>
</head>
<body>
  <h1>Uploading...</h1>
  <div class="progress" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
    <div class="progress-fill">0%</div>
  </div>

  <script>
    const bar = document.querySelector(".progress");
    const fill = document.querySelector(".progress-fill");
    let value = 0;

    function setProgress(percent) {
      fill.style.width = percent + "%";
      fill.textContent = percent + "%";
      bar.setAttribute("aria-valuenow", percent);
    }

    // demo: go up by 5% every half second until 100%
    const timer = setInterval(function () {
      value = value + 5;
      setProgress(value);
      if (value >= 100) clearInterval(timer);
    }, 500);
  </script>
</body>
</html>

How to use this code

  1. Get the file. Press Download above the code to save it as progress-bar.html. Or press Copy code, paste it into a plain text editor (Notepad on Windows, TextEdit in plain-text mode on a Mac, or a code editor such as VS Code) and save it as progress-bar.html. The name must end in .html, not .txt.
  2. Open it. Double-click the file. It opens in your web browser and starts working straight away.
  3. Change it. Open the same file in the text editor, edit something, save, and refresh the browser page to see the result.

Nothing needs to be installed, and the file works without an internet connection.

How it works

Two boxes

Smooth movement

transition: width 0.4s ease tells the browser to animate any change of width over 0.4 seconds, so the bar glides instead of jumping.

Accessibility

role="progressbar" and the three aria-value attributes let screen readers announce "progress bar, 65 percent". The setProgress function updates aria-valuenow every time the width changes, so the two always agree.

Making it move

In a real project you would call setProgress when something actually progresses, such as a file upload or the steps of a form. The setInterval loop here is only a demo that adds 5% every half second and stops at 100.

Add stripes

Add these lines to .progress-fill for diagonal stripes:

background-image: linear-gradient(45deg,
  rgba(255,255,255,.25) 25%, transparent 25%, transparent 50%,
  rgba(255,255,255,.25) 50%, rgba(255,255,255,.25) 75%, transparent 75%, transparent);
background-size: 20px 20px;

To make the stripes move, add animation: stripes 1s linear infinite; and this rule:

@keyframes stripes {
  from { background-position: 20px 0; }
  to   { background-position: 0 0; }
}

Or use the built-in element

HTML also has a ready-made <progress value="65" max="100"></progress> element. It is accessible by default, but each browser draws it differently and it is awkward to style, which is why custom bars like this one are so common.

FAQ

How do I change the progress bar value with JavaScript?

Set the fill's width, for example fill.style.width = "80%", and update aria-valuenow to the same number.

How do I make a circular progress bar?

That needs a different technique, usually an SVG circle with a stroke-dasharray, or a conic-gradient background in CSS.

Can I use this code in my project?

Yes. The code on this page is free to use, change and publish.

More tools

See all tools

Keep reading