Progress Bar

Linear progress indicator.

Uploading files 62%

html

<div class="progress-bar">
  <div class="progress-bar__row">
    <span class="progress-bar__label">Uploading files</span>
    <span class="progress-bar__value">62%</span>
  </div>
  <div class="progress-bar__track" role="progressbar" aria-label="Uploading files" aria-valuemin="0" aria-valuemax="100" aria-valuenow="62">
    <div class="progress-bar__fill" style="width:62%;background:#A8E6C1;"></div>
  </div>
</div>
<style>
.progress-bar { width: 260px; font: 12.5px/1 system-ui, sans-serif; color: #241430; }
.progress-bar__row { display: flex; justify-content: space-between; margin-bottom: 6px; }
.progress-bar__value { font-weight: 700; }
.progress-bar__track { height: 8px; border-radius: 999px; background: #24143018; overflow: hidden; }
.progress-bar__fill { height: 100%; border-radius: 999px; }
.progress-bar--indeterminate .progress-bar__fill { width: 40% !important; }
@keyframes progress-bar-slide { 0% { margin-left: -40%; } 100% { margin-left: 100%; } }
@media (prefers-reduced-motion: no-preference) {
  .progress-bar__fill { transition: width .2s ease; }
  .progress-bar--indeterminate .progress-bar__fill { animation: progress-bar-slide .2s ease-in-out infinite; }
}
</style>

tailwind

<div class="progress-bar-tw w-64 font-sans text-[12.5px] text-[#241430]">
  <div class="flex justify-between mb-1.5">
    <span>Uploading files</span>
    <span class="font-bold">62%</span>
  </div>
  <div role="progressbar" aria-label="Uploading files" aria-valuemin="0" aria-valuemax="100" aria-valuenow="62" class="h-2 rounded-full bg-[#24143018] overflow-hidden">
    <div class="progress-bar-tw__fill h-full rounded-full motion-safe:transition-[width] motion-safe:duration-300" style="width:62%;background:#A8E6C1;"></div>
  </div>
</div>
<style>
.progress-bar-tw--indeterminate .progress-bar-tw__fill { width: 40% !important; }
@keyframes progress-bar-tw-slide { 0% { margin-left: -40%; } 100% { margin-left: 100%; } }
@media (prefers-reduced-motion: no-preference) {
  .progress-bar-tw--indeterminate .progress-bar-tw__fill { animation: progress-bar-tw-slide .2s ease-in-out infinite; }
}
</style>

react

export function ProgressBar({
  label = "Uploading files",
  value = 62,
  color = "#A8E6C1",
  indeterminate = false,
}) {
  return (
    <div style={{ width: 260, font: "12.5px/1 system-ui, sans-serif", color: "#241430" }}>
      <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 6 }}>
        <span>{label}</span>
        {!indeterminate && <span style={{ fontWeight: 700 }}>{value}%</span>}
      </div>
      <div role="progressbar" aria-label={label} aria-valuemin={0} aria-valuemax={100}
        aria-valuenow={indeterminate ? undefined : value}
        style={{ height: 8, borderRadius: 999, background: "#24143018", overflow: "hidden" }}>
        <div className={indeterminate ? "pb-fill pb-fill--indeterminate" : "pb-fill"} style={{ height: "100%", borderRadius: 999, background: color,
          width: indeterminate ? "40%" : `${value}%` }} />
      </div>
      <style>{`
        @media (prefers-reduced-motion: no-preference) {
          .pb-fill { transition: width .2s ease; }
          .pb-fill--indeterminate { animation: progress-bar-react-slide 1.2s ease-in-out infinite; }
          @keyframes progress-bar-react-slide { 0% { margin-left: -40%; } 100% { margin-left: 100%; } }
        }
      `}</style>
    </div>
  );
}