Progress
Progress indicator using the native HTML progress element with semantic variants and sizes. Works by default, enhances with data attributes.
Example
<progress class="omni-progress" value="70" max="100" aria-label="Loading progress: 70%">70%</progress>
<div data-variant="primary">
<progress class="omni-progress" value="45" max="100" aria-label="Primary progress: 45%">45%</progress>
</div>
<div data-variant="success">
<progress class="omni-progress" value="85" max="100" aria-label="Success progress: 85%">85%</progress>
</div>
Variants
Semantic Variants
Wrap the progress element in a container with data-variant to convey meaning through color:
Default (Primary)
Secondary
Success
Warning
Danger
<div data-variant="secondary">
<progress class="omni-progress" value="60" max="100" aria-label="Secondary progress: 60%">60%</progress>
</div>
<div data-variant="success">
<progress class="omni-progress" value="60" max="100" aria-label="Success progress: 60%">60%</progress>
</div>
<div data-variant="warning">
<progress class="omni-progress" value="60" max="100" aria-label="Warning progress: 60%">60%</progress>
</div>
<div data-variant="danger">
<progress class="omni-progress" value="60" max="100" aria-label="Danger progress: 60%">60%</progress>
</div>
Sizes
Use data-size to adjust progress bar height:
Small (0.5rem)
Medium (0.75rem - default)
Large (1.25rem)
<progress class="omni-progress" data-size="sm" value="50" max="100">50%</progress>
<progress class="omni-progress" value="50" max="100">50%</progress>
<progress class="omni-progress" data-size="lg" value="50" max="100">50%</progress>
Indeterminate State
Omit the value attribute for an indeterminate/loading state:
Indeterminate Default
Indeterminate Primary
Indeterminate Success
<!-- No value attribute creates indeterminate state -->
<progress class="omni-progress" aria-label="Loading" aria-busy="true">Loading...</progress>
<div data-variant="primary">
<progress class="omni-progress" aria-label="Processing" aria-busy="true">Processing...</progress>
</div>
States
Paused
Add the paused class for a pulsing paused state:
<div data-variant="warning">
<progress class="omni-progress paused" value="45" max="100" aria-label="Paused at 45%">45%</progress>
</div>
Error
Add the error class for error state styling:
<progress class="omni-progress error" value="25" max="100" aria-label="Error at 25%">25%</progress>
API Reference
| Attribute | Values | Default | Description |
|---|---|---|---|
value |
number | — | Current progress value (omit for indeterminate) |
max |
number | 1 | Maximum progress value |
data-size |
sm, md, lg | md | Progress bar height |
class="paused" |
— | — | Adds pulsing animation for paused state |
class="error" |
— | — | Applies error state styling (danger color) |
Variant System
Note: The progress element itself doesn't take data-variant. Instead, wrap it in a container with the variant attribute:
| Container Attribute | Values | Default | Description |
|---|---|---|---|
data-variant |
primary, secondary, success, warning, danger | primary | Semantic color variant applied to progress bar |
Accessibility
- Uses semantic
<progress>element with native browser accessibility - Always include
aria-labeldescribing the progress (e.g., "Upload progress: 70%") - For indeterminate states, add
aria-busy="true"to indicate activity - Consider
aria-live="polite"for dynamic progress updates - Color states (danger/warning/success) should include descriptive labels (e.g., "Upload progress: 30%, low")
- Fallback text content between tags provides context for screen readers
- Respects
prefers-reduced-motionby disabling animations - Smooth transitions provide visual feedback for sighted users
Example with Full Accessibility
<!-- Determinate progress -->
<div data-variant="success">
<progress
class="omni-progress"
value="75"
max="100"
aria-label="Upload progress: 75%, high"
>75% complete</progress>
</div>
<!-- Indeterminate progress -->
<div data-variant="primary">
<progress
class="omni-progress"
aria-label="Loading content"
aria-busy="true"
aria-live="polite"
>Loading...</progress>
</div>