Progress
Visual indicators for loading states, task progress, and ongoing operations. Keep users informed about what's happening.
Interactive Demo
Drag the slider to see progress bar animation.
Loading...
50%
Linear Progress Bar
Show determinate progress for tasks with known completion percentage.
Uploading...
25%
Processing...
60%
Almost done!
90%
<div class="progress-bar">
<div class="progress-fill" style="width: 60%"></div>
</div>
Indeterminate Progress
For operations with unknown duration.
Loading...
<div class="progress-bar">
<div class="progress-fill progress-indeterminate"></div>
</div>
Size Variants
Different sizes for various contexts.
Slim
Default
Large
<div class="progress-bar progress-bar-sm">...</div>
<div class="progress-bar">...</div>
<div class="progress-bar progress-bar-lg">...</div>
Persona Colors
Use persona accent colors for branded progress indicators.
Ferni
Maya
Jordan
<div class="progress-fill progress-ferni" style="width: 80%"></div>
<div class="progress-fill progress-maya" style="width: 65%"></div>
<div class="progress-fill progress-jordan" style="width: 45%"></div>
Circular Spinner
Classic loading spinner for async operations.
Small
Default
Large
<div class="spinner spinner-sm"></div>
<div class="spinner"></div>
<div class="spinner spinner-lg"></div>
Persona Spinners
Spinners with persona accent colors.
Ferni
Maya
Alex
Jordan
Peter
Nayan
<div class="spinner spinner-ferni"></div>
<div class="spinner spinner-maya"></div>
Pulse Loader
Gentle pulsing animation for background loading.
<div class="pulse-loader">
<div class="pulse-dot"></div>
<div class="pulse-dot"></div>
<div class="pulse-dot"></div>
</div>
Button Loading States
Inline loading indicators for buttons.
<button class="btn btn-primary btn-loading">
<div class="spinner spinner-sm spinner-white"></div>
<span>Saving...</span>
</button>
Skeleton Loading
Placeholder content while data loads.
<div class="skeleton-card">
<div class="skeleton-avatar"></div>
<div class="skeleton-content">
<div class="skeleton-line skeleton-line-title"></div>
<div class="skeleton-line"></div>
</div>
</div>
Step Progress
Multi-step process indicator.
2
Profile
3
Preferences
4
Complete
<div class="step-progress">
<div class="step completed">
<div class="step-indicator">✓</div>
<span class="step-label">Account</span>
</div>
<div class="step-connector completed"></div>
<div class="step active">
<div class="step-indicator">2</div>
<span class="step-label">Profile</span>
</div>
...
</div>
CSS Implementation
/* Linear Progress Bar */
.progress-bar {
width: 100%;
height: 8px;
background: var(--bg-tertiary);
border-radius: var(--radius-full);
overflow: hidden;
}
.progress-bar-sm { height: 4px; }
.progress-bar-lg { height: 12px; }
.progress-fill {
height: 100%;
background: var(--accent-primary);
border-radius: var(--radius-full);
transition: width var(--duration-normal) var(--ease-ease-out);
}
/* Indeterminate Animation */
.progress-indeterminate {
width: 30% !important;
animation: indeterminate 1.5s ease-in-out infinite;
}
@keyframes indeterminate {
0% { transform: translateX(-100%); }
100% { transform: translateX(400%); }
}
/* Persona Colors */
.progress-ferni { background: var(--persona-ferni); }
.progress-maya { background: var(--persona-maya); }
.progress-jordan { background: var(--persona-jordan); }
/* Spinner */
.spinner {
width: 24px;
height: 24px;
border: 3px solid var(--border-subtle);
border-top-color: var(--accent-primary);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
.spinner-sm { width: 16px; height: 16px; border-width: 2px; }
.spinner-lg { width: 40px; height: 40px; border-width: 4px; }
.spinner-white { border-color: rgba(255,255,255,0.3); border-top-color: white; }
.spinner-ferni { border-top-color: var(--persona-ferni); }
.spinner-maya { border-top-color: var(--persona-maya); }
@keyframes spin {
to { transform: rotate(360deg); }
}
/* Pulse Loader */
.pulse-loader {
display: flex;
gap: var(--space-2);
}
.pulse-dot {
width: 10px;
height: 10px;
background: var(--accent-primary);
border-radius: 50%;
animation: pulse 1.4s ease-in-out infinite;
}
.pulse-dot:nth-child(2) { animation-delay: 0.2s; }
.pulse-dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes pulse {
0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
40% { opacity: 1; transform: scale(1); }
}
/* Skeleton */
.skeleton-line {
height: 12px;
background: linear-gradient(
90deg,
var(--bg-tertiary) 25%,
var(--bg-secondary) 50%,
var(--bg-tertiary) 75%
);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border-radius: var(--radius-sm);
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
/* Step Progress */
.step-progress {
display: flex;
align-items: center;
}
.step {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--space-2);
}
.step-indicator {
width: 32px;
height: 32px;
border: 2px solid var(--border-medium);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: var(--font-weight-semibold);
font-size: var(--text-sm);
color: var(--text-muted);
background: var(--bg-primary);
}
.step.active .step-indicator {
border-color: var(--accent-primary);
color: var(--accent-primary);
}
.step.completed .step-indicator {
background: var(--accent-primary);
border-color: var(--accent-primary);
color: white;
}
.step-connector {
flex: 1;
height: 2px;
background: var(--border-subtle);
margin: 0 var(--space-2);
}
.step-connector.completed {
background: var(--accent-primary);
}
Accessibility
- ARIA roles: Use
role="progressbar"witharia-valuenow,aria-valuemin,aria-valuemax - Live regions: Announce progress updates with
aria-live="polite" - Reduced motion: Respect
prefers-reduced-motion- use opacity changes instead of animation - Focus management: Don't trap focus during loading states
- Text alternatives: Provide status text for screen readers, not just visual indicators
Usage Guidelines
✓ Do
- Use determinate progress when completion is known
- Show estimated time for long operations
- Allow cancellation when possible
- Use skeleton loaders for content-heavy pages
✗ Don't
- Use progress bars for instant operations
- Show multiple spinners simultaneously
- Block the entire UI during loading
- Use animation-heavy loaders on low-end devices