Form Control
HTML5
The progress element represents the completion progress of a task, such as file uploads, downloads, installations, or any process moving toward completion.
Interactive code playground requires JavaScript. Here's the code:
<p>File Upload:</p>
<progress value="70" max="100">70%</progress>
<p>Installation Progress:</p>
<progress value="45" max="100">45% complete</progress>
<p>Loading (indeterminate):</p>
<progress>Loading...</progress>
<!-- Determinate progress (known completion) -->
< progress value = " 50 " max = " 100 " > 50% </ progress >
<!-- Indeterminate progress (unknown completion) -->
< progress > Loading... </ progress >
The text content serves as a fallback for browsers that don’t support <progress>.
Attribute Description Example valueCurrent progress value value="75"maxMaximum value (default: 1) max="100"
Interactive code playground requires JavaScript. Here's the code:
<p><strong>Uploading document.pdf</strong></p>
<progress id="upload" value="0" max="100">0%</progress>
<span id="upload-text">0%</span>
<button type="button" onclick="simulateUpload()">Start Upload</button>
<script>
function simulateUpload() {
let progress = 0;
const progressBar = document.getElementById('upload');
const text = document.getElementById('upload-text');
const interval = setInterval(() => {
progress += 10;
progressBar.value = progress;
text.textContent = progress + '%';
if (progress >= 100) {
clearInterval(interval);
text.textContent = 'Complete!';
}
}, 500);
}
</script>
Interactive code playground requires JavaScript. Here's the code:
<p><strong>Downloading update.zip (25 MB)</strong></p>
<progress id="download" value="0" max="100">0%</progress>
<div id="download-info">0 MB / 25 MB (0%)</div>
<button type="button" onclick="simulateDownload()">Start Download</button>
<script>
function simulateDownload() {
let progress = 0;
const progressBar = document.getElementById('download');
const info = document.getElementById('download-info');
const interval = setInterval(() => {
progress += 5;
const mb = (25 * progress / 100).toFixed(1);
progressBar.value = progress;
info.textContent = `${mb} MB / 25 MB (${progress}%)`;
if (progress >= 100) {
clearInterval(interval);
info.textContent = 'Download complete!';
}
}, 300);
}
</script>
Interactive code playground requires JavaScript. Here's the code:
<p><strong>Installing Software...</strong></p>
<progress id="install" value="0" max="100">0%</progress>
<p id="install-step">Preparing installation...</p>
<button type="button" onclick="simulateInstall()">Start Installation</button>
<script>
function simulateInstall() {
const steps = [
{ progress: 20, text: 'Extracting files...' },
{ progress: 40, text: 'Copying files...' },
{ progress: 60, text: 'Registering components...' },
{ progress: 80, text: 'Configuring settings...' },
{ progress: 100, text: 'Installation complete!' }
];
let index = 0;
const progressBar = document.getElementById('install');
const stepText = document.getElementById('install-step');
const interval = setInterval(() => {
if (index < steps.length) {
progressBar.value = steps[index].progress;
stepText.textContent = steps[index].text;
index++;
} else {
clearInterval(interval);
}
}, 1000);
}
</script>
Interactive code playground requires JavaScript. Here's the code:
<form id="submit-form">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<button type="submit">Submit</button>
</form>
<div id="progress-container" style="display: none;">
<p>Submitting form...</p>
<progress id="submit-progress" value="0" max="100">0%</progress>
<span id="submit-text">0%</span>
</div>
<script>
document.getElementById('submit-form').addEventListener('submit', (e) => {
e.preventDefault();
document.getElementById('progress-container').style.display = 'block';
let progress = 0;
const progressBar = document.getElementById('submit-progress');
const text = document.getElementById('submit-text');
const interval = setInterval(() => {
progress += 20;
progressBar.value = progress;
text.textContent = progress + '%';
if (progress >= 100) {
clearInterval(interval);
text.textContent = 'Form submitted successfully!';
}
}, 400);
});
</script>
Interactive code playground requires JavaScript. Here's the code:
<div style="height: 150px; overflow-y: scroll; border: 1px solid #ccc; padding: 10px;" id="article">
<h3>Scroll to Read</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident.</p>
<p>Sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem.</p>
</div>
<p>Reading Progress:</p>
<progress id="reading" value="0" max="100">0%</progress>
<span id="reading-text">0%</span>
<script>
const article = document.getElementById('article');
const progressBar = document.getElementById('reading');
const text = document.getElementById('reading-text');
article.addEventListener('scroll', () => {
const scrollHeight = article.scrollHeight - article.clientHeight;
const scrolled = (article.scrollTop / scrollHeight) * 100;
const progress = Math.min(Math.round(scrolled), 100);
progressBar.value = progress;
text.textContent = progress + '%';
});
</script>
Interactive code playground requires JavaScript. Here's the code:
<p><strong>Loading Video</strong></p>
<progress id="video-load" value="0" max="100">0%</progress>
<span id="video-text">Buffering... 0%</span>
<button type="button" onclick="simulateVideoLoad()">Load Video</button>
<script>
function simulateVideoLoad() {
let progress = 0;
const progressBar = document.getElementById('video-load');
const text = document.getElementById('video-text');
const interval = setInterval(() => {
progress += Math.floor(Math.random() * 15) + 5;
if (progress > 100) progress = 100;
progressBar.value = progress;
text.textContent = `Buffering... ${progress}%`;
if (progress >= 100) {
clearInterval(interval);
text.textContent = 'Ready to play!';
}
}, 500);
}
</script>
Interactive code playground requires JavaScript. Here's the code:
<p><strong>Processing Request</strong></p>
<progress>Loading...</progress>
<p>Please wait while we process your request.</p>
<p><small>
When the 'value' attribute is omitted, the progress bar shows
an indeterminate state (animated but no specific progress).
</small></p>
Interactive code playground requires JavaScript. Here's the code:
<div id="status-container">
<p id="status-text">Click to start</p>
<progress id="status-bar"></progress>
</div>
<button type="button" onclick="toggleProgress()">Toggle Progress</button>
<script>
let isIndeterminate = true;
function toggleProgress() {
const bar = document.getElementById('status-bar');
const text = document.getElementById('status-text');
if (isIndeterminate) {
bar.value = 50;
bar.max = 100;
text.textContent = 'Determinate: 50%';
} else {
bar.removeAttribute('value');
bar.removeAttribute('max');
text.textContent = 'Indeterminate: Processing...';
}
isIndeterminate = !isIndeterminate;
}
</script>
Interactive code playground requires JavaScript. Here's the code:
<p><strong>Multi-step Process</strong></p>
<progress id="multi-step" value="0" max="100">0%</progress>
<p id="step-info">Step 0 of 5</p>
<button type="button" onclick="nextStep()">Next Step</button>
<button type="button" onclick="resetSteps()">Reset</button>
<script>
let currentStep = 0;
const totalSteps = 5;
function nextStep() {
if (currentStep < totalSteps) {
currentStep++;
updateProgress();
}
}
function resetSteps() {
currentStep = 0;
updateProgress();
}
function updateProgress() {
const progress = (currentStep / totalSteps) * 100;
document.getElementById('multi-step').value = progress;
document.getElementById('step-info').textContent =
`Step ${currentStep} of ${totalSteps}${currentStep === totalSteps ? ' - Complete!' : ''}`;
}
updateProgress();
</script>
Interactive code playground requires JavaScript. Here's the code:
<style>
.custom-progress {
width: 100%;
height: 30px;
border-radius: 15px;
overflow: hidden;
}
/* Firefox */
.custom-progress::-moz-progress-bar {
background: linear-gradient(90deg, #3b82f6, #2563eb);
}
/* Chrome/Safari */
.custom-progress::-webkit-progress-bar {
background: #e5e7eb;
border-radius: 15px;
}
.custom-progress::-webkit-progress-value {
background: linear-gradient(90deg, #3b82f6, #2563eb);
border-radius: 15px;
}
</style>
<p>Custom Styled Progress:</p>
<progress class="custom-progress" value="65" max="100">65%</progress>
Interactive code playground requires JavaScript. Here's the code:
<style>
.animated-progress {
width: 100%;
height: 25px;
}
.animated-progress::-webkit-progress-value {
background: linear-gradient(90deg, #10b981, #059669);
transition: width 0.3s ease;
}
.animated-progress::-moz-progress-bar {
background: linear-gradient(90deg, #10b981, #059669);
transition: width 0.3s ease;
}
</style>
<progress id="animated" class="animated-progress" value="0" max="100">0%</progress>
<button type="button" onclick="animateProgress()">Animate</button>
<script>
function animateProgress() {
let progress = 0;
const bar = document.getElementById('animated');
const interval = setInterval(() => {
progress += 2;
bar.value = progress;
if (progress >= 100) {
clearInterval(interval);
setTimeout(() => { bar.value = 0; }, 500);
}
}, 50);
}
</script>
Interactive code playground requires JavaScript. Here's the code:
<style>
.progress-container {
margin: 15px 0;
}
.progress-low::-webkit-progress-value { background: #ef4444; }
.progress-low::-moz-progress-bar { background: #ef4444; }
.progress-medium::-webkit-progress-value { background: #f59e0b; }
.progress-medium::-moz-progress-bar { background: #f59e0b; }
.progress-high::-webkit-progress-value { background: #10b981; }
.progress-high::-moz-progress-bar { background: #10b981; }
</style>
<div class="progress-container">
<p>Low (25%):</p>
<progress class="progress-low" value="25" max="100">25%</progress>
</div>
<div class="progress-container">
<p>Medium (50%):</p>
<progress class="progress-medium" value="50" max="100">50%</progress>
</div>
<div class="progress-container">
<p>High (90%):</p>
<progress class="progress-high" value="90" max="100">90%</progress>
</div>
Interactive code playground requires JavaScript. Here's the code:
<style>
.progress-wrapper {
position: relative;
width: 100%;
}
.progress-wrapper progress {
width: 100%;
height: 30px;
}
.progress-percentage {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-weight: 600;
font-size: 14px;
color: #1f2937;
}
</style>
<div class="progress-wrapper">
<progress value="73" max="100">73%</progress>
<span class="progress-percentage">73%</span>
</div>
<!-- Moving toward 100% completion -->
< progress value = " 60 " max = " 100 " > 60% </ progress >
Use for: File uploads/downloads, installation progress, task completion, loading indicators, or any process moving toward completion.
<!-- Current measurement in a range -->
< meter value = " 60 " min = " 0 " max = " 100 " > 60% </ meter >
Use for: Disk usage, battery level, temperature, ratings/scores, or static/fluctuating measurements.
Interactive code playground requires JavaScript. Here's the code:
<p><strong>Progress (uploading file)</strong></p>
<progress value="60" max="100">60%</progress>
<span>Uploading... 60%</span>
<p><strong>Meter (disk usage)</strong></p>
<meter value="60" min="0" max="100" low="70" high="90">60%</meter>
<span>Disk: 60% full</span>
Interactive code playground requires JavaScript. Here's the code:
<p>Processing data:</p>
<progress value="45" max="100">45% complete</progress>
The text content serves as a fallback and is announced by screen readers.
Interactive code playground requires JavaScript. Here's the code:
<label for="file-progress">File Upload Progress:</label>
<progress id="file-progress" value="67" max="100">67% uploaded</progress>
Interactive code playground requires JavaScript. Here's the code:
<div role="region" aria-live="polite">
<p id="upload-status">Uploading document.pdf</p>
<progress id="upload-prog" value="0" max="100">0%</progress>
<span id="upload-pct" aria-live="polite">0%</span>
</div>
<button type="button" onclick="startUpload()">Start Upload</button>
<script>
function startUpload() {
let progress = 0;
const bar = document.getElementById('upload-prog');
const pct = document.getElementById('upload-pct');
const status = document.getElementById('upload-status');
const interval = setInterval(() => {
progress += 10;
bar.value = progress;
pct.textContent = progress + '%';
if (progress >= 100) {
clearInterval(interval);
status.textContent = 'Upload complete!';
}
}, 500);
}
</script>
Interactive code playground requires JavaScript. Here's the code:
<p role="status" aria-live="polite">
Processing your request, please wait...
</p>
<progress aria-label="Processing request">Loading...</progress>
// Update every 100ms for smooth progress
progressBar . value = progress ;
// Large jumps look jarring
progressBar . value = progress ;
< p > Uploading report.pdf (2.5 MB) </ p >
< progress value = " 50 " max = " 100 " > 50% </ progress >
< p > 1.25 MB / 2.5 MB (50%) </ p >
< progress value = " 50 " max = " 100 " > 50% </ progress >
Interactive code playground requires JavaScript. Here's the code:
<div id="task-container">
<p id="task-status">Click to start task</p>
<progress id="task-bar" value="0" max="100">0%</progress>
<span id="task-pct">0%</span>
</div>
<button type="button" onclick="runTask()">Start Task</button>
<script>
function runTask() {
let progress = 0;
const bar = document.getElementById('task-bar');
const pct = document.getElementById('task-pct');
const status = document.getElementById('task-status');
status.textContent = 'Processing...';
const interval = setInterval(() => {
progress += 5;
bar.value = progress;
pct.textContent = progress + '%';
if (progress >= 100) {
clearInterval(interval);
status.textContent = 'Task completed successfully!';
status.style.color = '#10b981';
status.style.fontWeight = 'bold';
}
}, 200);
}
</script>
Browser Version Notes Chrome 8+ Full support Firefox 16+ Full support Safari 6+ Full support Edge 12+ Full support IE 10+ Partial support