Indeterminate Bar

비확정 진행바

Two bars stretching and sliding on offset timings to read as one continuous flow — the web's most common top-of-page loading bar.

Also known as: Linear indeterminate progressMaterial linear loader
···
html
<div class="wrap" role="status" aria-live="polite" aria-busy="true">
  <div class="track" aria-hidden="true"><div class="ib ib1"></div><div class="ib ib2"></div></div>
  <span class="cap">두 막대 scaleX + translateX 오프셋</span>
</div>
css
.wrap{display:flex;flex-direction:column;align-items:center;gap:16px;width:min(76%,260px)}
.track{position:relative;width:100%;height:clamp(6px,1.8vmin,9px);border-radius:999px;background:var(--line);overflow:hidden}
.ib{position:absolute;top:0;bottom:0;left:0;width:100%;border-radius:999px;transform-origin:left center}
.ib1{background:var(--accent);animation:ib1 2.1s cubic-bezier(.65,.815,.735,.395) infinite}
.ib2{background:var(--accent-2);animation:ib2 2.1s cubic-bezier(.165,.84,.44,1) infinite .9s}
@keyframes ib1{0%{transform:translateX(-100%) scaleX(.1)}55%{transform:translateX(20%) scaleX(.85)}100%{transform:translateX(110%) scaleX(.1)}}
@keyframes ib2{0%{transform:translateX(-140%) scaleX(.1)}55%{transform:translateX(10%) scaleX(.6)}100%{transform:translateX(110%) scaleX(.1)}}
.cap{font-size:clamp(9px,2.4vmin,11px);color:var(--muted);letter-spacing:.02em}

The standard indeterminate cue for a page transition or route change — "something's happening, duration unknown." Once bytes can be counted, as in an upload, a determinate progress-bar in the same spot serves the user far better.

Borrowed from the Material Design spec: two bars sit absolutely positioned inside a track, each animating transform: scaleX and translateX on a different duration and start offset. The timings have to overlap so the next bar appears before the first one shrinks away, which is what reads as continuous rather than choppy.

Skip it for loads under 200ms, and pair it with a skeleton for a long transition covering most of the screen. role="progressbar" is misleading when there's no real progress to report — give the container role="status", aria-live="polite" and aria-busy="true" instead. Under prefers-reduced-motion, you can replace the two moving bars with a faint pulse across the whole track.