10 CSS progress bars worth copying (with full source)
Ten animated progress bars in pure CSS: striped, gradient, segmented, indeterminate, dual-track. All free to copy, all render to MP4.
The progress bar is the most-implemented and least-thought-about UI element. Every product ships at least three: file uploads, multi-step forms, video scrubbers. Most of them look the same because most engineers reach for the default <progress> element and stop.
Here are ten progress bars worth copying, each with the full source. They're CSS-only, deterministic, and render straight to MP4 if you need them in a loading-screen onboarding video.
1. The simple fill
The baseline. A track, a fill, a width transition. Add a 200ms ease-out and it's already better than 80% of what ships.
<div class="bar"><div class="fill" style="width:62%"></div></div>.bar { height: 6px; background: #1a1a1a; border-radius: 999px; overflow: hidden; }
.fill { height: 100%; background: #ff3b1f; transition: width .2s ease-out; }2. The animated stripes (determinate)
Classic loading-bar feel: a striped fill that scrolls slowly. Use a background-image gradient with 45° stripes.
3. The indeterminate loop
For "I don't know how long this will take." A small bright segment slides across the full track on a 1.5s loop.
.fill {
position: absolute; height: 100%; width: 30%; background: #ff3b1f;
border-radius: 999px;
animation: indet 1.5s cubic-bezier(.4,0,.2,1) infinite;
}
@keyframes indet {
0% { left: -30%; }
100% { left: 100%; }
}4. The gradient sweep
A fill with an animated color gradient — implies activity even when the width isn't changing.
5. The segmented bar
For multi-step flows. Five (or N) discrete pills, the completed ones filled.
<div class="seg" data-step="3">
<span></span><span></span><span></span><span></span><span></span>
</div>.seg { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; }
.seg span { height: 4px; background: #1a1a1a; border-radius: 999px; }
.seg span:nth-child(-n+3) { background: #ff3b1f; }6. The dual-track (upload + processing)
A bar showing two pipelines at once: the lower track is fully filled (upload done), the upper is partial (processing in progress). Useful for "uploaded, now transcoding" flows.
7. The radial / circular bar
When the bar should fit inside a card, not stretch across one. SVG circle with stroke-dashoffset. See animated pie chart for the same primitive applied to ratio charts.
8. The wave bar
For audio uploads. A row of vertical bars, each with a randomized phase, swaying. Five lines of CSS keyframes. The "audio waveform that means nothing" trope, but useful where you genuinely don't have a real waveform yet.
9. The number-mirror bar
A bar with the percentage value mirrored in big type underneath. The two animate together. For dashboard "headline number" hero shots, this is the move.
<div class="hero">
<div class="bar"><div class="fill" style="width:62%"></div></div>
<div class="num">62<span>%</span></div>
</div>The number uses tabular-nums and counts up alongside the width. Pair it with an animated counter for the count logic.
10. The "step ticker" bar
Combines the segmented bar with a label per step. Used in checkout flows, onboarding wizards, anywhere the user needs to know "step 3 of 5" without thinking.
Calibration rules
Three rules that apply across all ten:
- Determinate bars use width transitions, not animations. A
transition: width 0.2ssnaps cleanly to a new value; a keyframe animation will fight you when the value changes mid-animation. - Indeterminate bars use animations, never transitions. Animation runs deterministically; you don't want the indeterminate state to interpolate when the loop restarts.
- Color = state, width = progress. Don't mix. A bar that changes from blue to green at 100% is two pieces of information competing for the same channel.
Rendering to video
All ten render straight to MP4 through the render pipeline since they're pure CSS. The common use case: a 4-second loop for "your file is processing" baked into a help video. The indeterminate bar (#3) is the right pick — it loops cleanly and reads as "active" without claiming a specific progress value.
Open the playground, pick a bar, drop it into a card, render the loop.
Cite this postBibTeX · APA · Markdown
@misc{park2026progress,
author = {Ren Park},
title = {10 CSS progress bars worth copying (with full source)},
year = {2026},
url = {https://hyperframes.video/blog/css-progress-bar-collection},
note = {HyperFrames blog}
}Ren Park. (2026, May 4). 10 CSS progress bars worth copying (with full source). HyperFrames. https://hyperframes.video/blog/css-progress-bar-collection
[10 CSS progress bars worth copying (with full source)](https://hyperframes.video/blog/css-progress-bar-collection) — Ren Park, 2026
Ren writes guides, runs workshops, and breaks the CLI on purpose so you do not have to. Previously dev rel at a CI company; before that, an actual filmmaker.
Stripe-style payment success animation in pure CSS
The animated checkmark, the elastic ring, the confetti — the full Stripe-style payment success animation in CSS. Free source, MP4 export.
Slack-style notification toast animation in CSS
Build a Slack-style notification toast: slide-in, hover-pause, swipe-to-dismiss, stacking. Pure CSS source, no animation libraries.
Skeleton loaders that don't feel cheap (CSS + timing)
Build skeleton loaders that match your design: shimmer technique, content-shape rules, timing curves, and when not to use them.
Building with HyperFrames? Come hang out.
We're on GitHub, in Discord, and the playground is one click away. Bring weird ideas — we collect them.