20 CSS Loaders 04 / 20

CSS Progress Bar Loader

Five animated CSS progress bars — fill sweep, animated stripes, gradient shimmer, indeterminate bounce, and segmented pulse — covering the most common loading-state UI patterns.

Pure CSS MIT licensed
Live Demo Open in tab

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

Open in playground

The code

<div class="ld-04">
  <div class="ld-04__stage">
    <div class="ld-04__item">
      <div class="ld-04__label"><span>Uploading file…</span><span>78%</span></div>
      <div class="ld-04__track"><div class="ld-04__fill"></div></div>
.ld-04,.ld-04 *,.ld-04 *::before,.ld-04 *::after{box-sizing:border-box;margin:0;padding:0}
.ld-04{
  --bg:#0c0c1d;--c1:#a78bfa;--c2:#06b6d4;--c3:#f472b6;--c4:#34d399;
  background:var(--bg);display:flex;align-items:center;justify-content:center;min-height:100vh;font-family:'Segoe UI',sans-serif;padding:40px;
}
.ld-04__stage{display:flex;flex-direction:column;gap:36px;width:100%;max-width:480px}
.ld-04__item{display:flex;flex-direction:column;gap:10px}
.ld-04__label{display:flex;justify-content:space-between;color:rgba(255,255,255,.6);font-size:12px;letter-spacing:.5px}
.ld-04__track{height:8px;background:rgba(255,255,255,.08);border-radius:99px;overflow:hidden;position:relative}

/* Standard fill */
.ld-04__fill{height:100%;border-radius:99px;background:var(--c1);animation:ld-04-fill1 2.5s ease-in-out infinite}
@keyframes ld-04-fill1{0%{width:0%}60%{width:78%}100%{width:78%}}

/* Striped animated */
.ld-04__striped{height:100%;border-radius:99px;background:repeating-linear-gradient(45deg,var(--c2) 0,var(--c2) 10px,rgba(255,255,255,.15) 10px,rgba(255,255,255,.15) 20px);background-size:200% 100%;width:60%;animation:ld-04-stripes 1s linear infinite}
@keyframes ld-04-stripes{to{background-position:-200% 0}}

/* Gradient shimmer */
.ld-04__gfill{height:100%;border-radius:99px;width:55%;background:linear-gradient(90deg,var(--c3),var(--c1),var(--c3));background-size:200% 100%;animation:ld-04-glow 1.5s ease-in-out infinite}
@keyframes ld-04-glow{0%{background-position:100% 0}100%{background-position:-100% 0}}

/* Indeterminate bounce */
.ld-04__bounce{height:100%;border-radius:99px;background:var(--c4);width:40%;animation:ld-04-bounce 1.8s ease-in-out infinite}
@keyframes ld-04-bounce{0%{transform:translateX(-100%)}50%{transform:translateX(150%)}100%{transform:translateX(-100%)}}

/* Segmented */
.ld-04__seg-track{display:flex;gap:4px}
.ld-04__seg{flex:1;height:8px;border-radius:4px;background:rgba(255,255,255,.08);animation:ld-04-seg 2s ease-in-out infinite}
.ld-04__seg:nth-child(1){animation-delay:0s}
.ld-04__seg:nth-child(2){animation-delay:.2s}
.ld-04__seg:nth-child(3){animation-delay:.4s}
.ld-04__seg:nth-child(4){animation-delay:.6s}
.ld-04__seg:nth-child(5){animation-delay:.8s}
@keyframes ld-04-seg{0%,100%{background:rgba(255,255,255,.08)}50%{background:var(--c1)}}

@media(prefers-reduced-motion:reduce){
  .ld-04__fill,.ld-04__striped,.ld-04__gfill,.ld-04__bounce,.ld-04__seg{animation:none;width:60%}
}

How this works

The standard fill bar animates width from 0% to 78% using ease-in-out timing to mimic a real upload percentage. The striped bar uses repeating-linear-gradient(45deg, ...) with a background-position animation rather than width changes — the track width stays fixed at 60% while the stripes scroll, giving the illusion of movement at a constant fill level.

The indeterminate bounce bar is a fixed-width fill that translateXes from -100% through 150% and back, staying fully within the overflow:hidden track. The segmented bar uses five sibling divs with a cascading background colour animation from neutral to --c1 and back — no widths change, making it ideal for step-progress indicators. The gradient shimmer bar animates background-position on an oversized gradient for a flowing metallic look.

Customize

  • Change the filled percentage of the sweep bar by editing the final width:78% keyframe value — combine with a CSS custom property for runtime JS control.
  • Adjust stripe angle from 45deg to -45deg for a reversed chevron effect, or 90deg for vertical stripes.
  • Increase track height by editing height:8px on .ld-04__track — use 4px for thin iOS-style bars or 16px for chunky progress indicators.
  • Add a label overlay by positioning a span absolutely inside the track with color: white; mix-blend-mode: difference so it inverts against the fill.
  • Convert to a circular progress ring by swapping track divs for SVG <circle> elements with stroke-dashoffset animation.

Watch out for

  • Animating width instead of transform: scaleX() for the fill bar triggers layout reflow — use transform-origin: left center with scaleX for better performance on long lists.
  • The indeterminate bounce requires overflow:hidden on the track; without it the bouncing fill element is visible outside the bar bounds.
  • The striped bar's background-position animation repaints on each frame in some older browsers — test on Android Chrome 80 and below if striped loaders are used in lists.

Browser support

ChromeSafariFirefoxEdge
49+ 10+ 44+ 49+

All techniques use standard transforms and gradients; no modern CSS features required.

Search CodeFronts

Loading…