<progress>
Represents the completion progress of a task
✨ HTML5Definition and Usage
The <progress> tag represents the completion
progress of a task, such as a download or file upload.
The <progress> tag is not suitable for
representing a gauge (e.g., disk space usage). For gauges, use the
<meter> tag instead.
The progress element can be used in two states:
- Determinate: Shows specific progress (when both value and max are specified)
- Indeterminate: Shows activity without specific progress (when only max is specified or no attributes)
<progress> tag together with JavaScript to
display dynamic progress updates.
<progress> element
is new in HTML5 and provides a semantic way to show task
completion.
Browser support and standards
Browser rendering and modern HTML conformance are different questions. Check the current element reference for the browsers and features your project needs; the older source version table is not a current compatibility guarantee.
Read the MDN element referenceAttributes
| Attribute | Value | Description |
|---|---|---|
| value | number | Specifies how much of the task has been completed. Must be a valid floating point number between 0 and max (or 0 and 1 if max is not specified) |
| max | number | Specifies how much work the task requires in total. Default value is 1.0 |
The <progress> tag also supports the
Global Attributes in HTML.
The <progress> tag also supports the
Event Attributes in HTML.
Examples
Basic Progress Bar
Create a simple progress bar showing 70% completion:
Example
<label for="file">Downloading progress:</label>
<progress id="file" value="70" max="100">70%</progress>
Indeterminate Progress
Show activity without specific progress (no value attribute):
Example
<label for="loading">Loading...</label>
<progress
id="loading"
></progress>
File Upload Progress
Display file upload progress with percentage:
Example
<p>Uploading file: <span id="percent">0</span>%</p>
<progress id="upload-progress" value="0" max="100">0%</progress>
<script>
let progress = 0;
const progressBar = document.getElementById('upload-progress');
const percentText = document.getElementById('percent');
const interval = setInterval(() => {
progress += 10;
progressBar.value = progress;
percentText.textContent = progress;
if (progress >= 100) {
clearInterval(interval);
}
}, 500);
</script>
Download Progress with JavaScript
Simulate a download with dynamic updates:
Example
<p>Download progress: <span id="status">Starting...</span></p>
<progress id="download" value="0" max="100"></progress>
<button onclick="startDownload()">Start Download</button>
<script>
function startDownload() {
const progress = document.getElementById('download');
const status = document.getElementById('status');
let value = 0;
const download = setInterval(() => {
value += Math.random() * 10;
if (value >= 100) {
value = 100;
status.textContent = 'Complete!';
clearInterval(download);
} else {
status.textContent = Math.floor(value) + '% downloaded';
}
progress.value = value;
}, 300);
}
</script>
Styled Progress Bar
Customize the appearance using CSS:
Example
<style>
progress {
width: 100%;
height: 30px;
border-radius: 15px;
}
/* WebKit browsers (Chrome, Safari) */
progress::-webkit-progress-bar {
background-color: #f0f0f0;
border-radius: 15px;
}
progress::-webkit-progress-value {
background: linear-gradient(90deg, #745af2, #667eea);
border-radius: 15px;
}
/* Firefox */
progress::-moz-progress-bar {
background: linear-gradient(90deg, #745af2, #667eea);
border-radius: 15px;
}
</style>
<label for="styled">Styled progress:</label>
<progress id="styled" value="65" max="100">65%</progress>
Multiple Progress Bars
Track multiple tasks simultaneously:
Example
<div>
<p>Task 1: Image Processing</p>
<progress value="45" max="100">45%</progress>
</div>
<div>
<p>Task 2: Data Upload</p>
<progress value="80" max="100">80%</progress>
</div>
<div>
<p>Task 3: Compression</p>
<progress value="20" max="100">20%</progress>
</div>
Animated Progress with Color Changes
Create an animated progress bar that changes color:
Example
<style>
.color-progress {
width: 100%;
height: 25px;
}
.color-progress::-webkit-progress-value {
transition: width 0.5s ease;
}
.low::-webkit-progress-value {
background-color: #f44336;
}
.medium::-webkit-progress-value {
background-color: #ff9800;
}
.high::-webkit-progress-value {
background-color: #4CAF50;
}
</style>
<progress id="color-bar" class="color-progress low" value="25" max="100">25%</progress>
<script>
const bar = document.getElementById('color-bar');
let val = 25;
setInterval(() => {
val = (val + 5) % 100;
bar.value = val;
if (val < 33) {
bar.className = 'color-progress low';
} else if (val < 66) {
bar.className = 'color-progress medium';
} else {
bar.className = 'color-progress high';
}
}, 500);
</script>
Progress vs Meter
Understanding the difference between
<progress> and <meter>:
| Feature | <progress> | <meter> |
|---|---|---|
| Purpose | Shows completion of a task in progress | Shows a measurement within a known range |
| Use Cases | Downloads, uploads, installations, loading | Disk usage, temperature, scores, ratings |
| Dynamic | Typically changes over time | Represents a static measurement at a point in time |
| Indeterminate State | Supported (no value attribute) | Not supported |
| Attributes | value, max | value, min, max, low, high, optimum |
<progress> for tasks that are in progress and
will eventually complete. Use <meter> for
measurements or gauges that represent a value within a range.
Styling Progress Bars
Different browsers use different pseudo-elements for styling:
-
WebKit/Blink (Chrome, Safari, Edge):
-
::-webkit-progress-bar- Styles the background/track -
::-webkit-progress-value- Styles the filled portion
-
-
Firefox:
-
::-moz-progress-bar- Styles the filled portion
-
Accessibility Considerations
- Always provide text content between the opening and closing tags as a fallback for older browsers
-
Use
aria-labelor associate with a<label>to describe what's progressing -
Update
aria-valuenow,aria-valuemin, andaria-valuemaxfor dynamic updates - Consider providing a text update alongside the visual progress bar
-
For indeterminate progress, use
aria-busy="true"on the container
Try it Yourself
Interactive Example
Best Practices
-
Use
<progress>for tasks that are in progress and will complete - Provide fallback text content between the tags for older browsers
- Always label progress bars with descriptive text
- Update progress values with JavaScript for dynamic tasks
- Use indeterminate state (no value) when duration is unknown
-
Combine with
aria-labelor<label>for accessibility - Show percentage text alongside the progress bar for clarity
- Test styling across different browsers for consistent appearance
-
Don't use for static measurements - use
<meter>instead
Default CSS Settings
Most browsers will display the
<progress> element with the following default
values:
Default CSS
Unavailable or blocked: markup context “Matching lesson markup is not supplied; this fragment uses a generic HTML scaffold.”. Provide inline styles and scripts, embedded images or the missing HTML context. External requests and browser dialogs stay blocked.
progress {
display: inline-block;
}