Open demo

CSS code

HTML
<div><span class="lbl">Upload queue</span><div class="card">
<div class="up">
  <div class="up-head"><b>Uploading 3 files</b><span>1 of 3 done</span></div>
  <ul class="up-list">
    <li class="up-row">
      <span class="up-file pdf" aria-hidden="true">PDF</span>
      <div class="up-body">
        <div class="up-top"><b id="up-f1">brand-guidelines-2026.pdf</b><span aria-hidden="true">62%</span></div>
        <div class="up-bar" role="progressbar" aria-labelledby="up-f1" aria-valuenow="62" aria-valuemin="0" aria-valuemax="100" aria-valuetext="62%, 4.2 MB of 6.8 MB" style="--v:62"><i></i></div>
        <div class="up-meta">4.2 MB of 6.8 MB · 8 seconds left</div>
      </div>
      <button class="up-btn" type="button" aria-label="Cancel upload of brand-guidelines-2026.pdf"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 5l10 10M15 5 5 15"/></svg></button>
    </li>
    <li class="up-row done">
      <span class="up-file jpg" aria-hidden="true">JPG</span>
      <div class="up-body">
        <div class="up-top"><b id="up-f2">hero-shot-final.jpg</b><span aria-hidden="true">Done</span></div>
        <div class="up-bar" role="progressbar" aria-labelledby="up-f2" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" aria-valuetext="Uploaded, 3.1 MB" style="--v:100"><i></i></div>
        <div class="up-meta">3.1 MB · Uploaded</div>
      </div>
      <button class="up-btn" type="button" aria-label="Remove hero-shot-final.jpg"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h12M8 6V4h4v2M6 6l1 10h6l1-10"/></svg></button>
    </li>
    <li class="up-row fail">
      <span class="up-file mov" aria-hidden="true">MOV</span>
      <div class="up-body">
        <div class="up-top"><b id="up-f3">product-demo-v3.mov</b><span aria-hidden="true">Failed</span></div>
        <div class="up-bar" role="progressbar" aria-labelledby="up-f3" aria-valuenow="38" aria-valuemin="0" aria-valuemax="100" aria-valuetext="Failed at 38%, connection lost" style="--v:38"><i></i></div>
        <div class="up-meta">Connection lost at 18.4 MB of 48.2 MB</div>
      </div>
      <button class="up-btn text" type="button" aria-label="Retry upload of product-demo-v3.mov">Retry</button>
    </li>
  </ul>
</div></div></div>

<div><span class="lbl">Download with pause and cancel</span><div class="card">
<div class="up up-dl">
  <div class="up-dl-top">
    <span class="up-dl-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4v11M7 10l5 5 5-5M5 20h14"/></svg></span>
    <div class="up-dl-name"><b id="up-dl">Figma-126.4-arm64.dmg</b><span class="up-meta">From figma.com · 2.4 MB/s</span></div>
    <div class="up-actions">
      <button class="up-btn" type="button" aria-label="Pause download of Figma-126.4-arm64.dmg"><svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><rect x="5" y="4" width="3.5" height="12" rx="1"/><rect x="11.5" y="4" width="3.5" height="12" rx="1"/></svg></button>
      <button class="up-btn" type="button" aria-label="Cancel download of Figma-126.4-arm64.dmg"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 5l10 10M15 5 5 15"/></svg></button>
    </div>
  </div>
  <div class="up-bar" role="progressbar" aria-labelledby="up-dl" aria-valuenow="59" aria-valuemin="0" aria-valuemax="100" aria-valuetext="59%, 184 MB of 312 MB, about 53 seconds left" style="--v:59"><i></i></div>
  <div class="up-dl-foot"><span><strong>184 MB</strong> of 312 MB</span><span>About 53 seconds left</span></div>
</div></div></div>

<div><span class="lbl">Toast with an edge bar</span><div class="card">
<div class="up up-toast">
  <div><b id="up-toast">Uploading 2 of 5 photos</b><span>40% · Lake Bled album</span></div>
  <button class="up-btn text" type="button" aria-label="Cancel uploading photos to Lake Bled album">Cancel</button>
  <div class="up-bar" role="progressbar" aria-labelledby="up-toast" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="--v:40"><i></i></div>
</div></div></div>
CSS
/* Upload and download rows. Each bar is role="progressbar" labelled by the file name, with the size in
   aria-valuetext; --v (0 to 100) sets the fill. The buttons name the file they act on, so a screen reader
   hears "Cancel upload of brand-guidelines.pdf" rather than a bare "Cancel". Wire them to your uploader. */
.up{--up-accent:#2563eb;--up-ok:#15803d;--up-bad:#dc2626;--up-track:#e3e8f0;--up-ink:#0f1b2d;--up-muted:#56627a;color:var(--up-ink)}
.up-head{display:flex;justify-content:space-between;align-items:baseline;gap:12px;margin-bottom:6px}
.up-head b{font-size:1rem}
.up-head span{font-size:.84rem;color:var(--up-muted)}
.up-list{list-style:none}
.up-row{display:flex;align-items:center;gap:14px;padding:14px 0;border-top:1px solid #edf1f6}
.up-row:first-child{border-top:0}
.up-row:last-child{padding-bottom:0}
.up-file{flex:none;display:grid;place-items:center;width:38px;height:44px;border-radius:8px;font-size:.62rem;font-weight:800;letter-spacing:.04em}
.up-file.pdf{background:#fee2e2;color:#b91c1c}
.up-file.jpg{background:#ede9fe;color:#6d28d9}
.up-file.mov{background:#dbeafe;color:#1d4ed8}
.up-body{flex:1;min-width:0;display:grid;grid-template-columns:minmax(0,1fr);gap:7px}
.up-top{display:flex;justify-content:space-between;gap:10px;font-size:.9rem}
.up-top b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}
.up-top span{flex:none;font-weight:700;font-variant-numeric:tabular-nums}
.up-bar{--v:0;height:6px;border-radius:999px;background:var(--up-track);overflow:hidden}
.up-bar>i{display:block;height:100%;width:calc(var(--v) * 1%);border-radius:inherit;background:var(--up-accent);transition:width .3s linear}
.up-meta{font-size:.8rem;color:var(--up-muted);font-variant-numeric:tabular-nums}
.up-row.done .up-bar>i{background:var(--up-ok)}
.up-row.done .up-top span{color:var(--up-ok)}
.up-row.fail .up-bar>i{background:var(--up-bad)}
.up-row.fail .up-top span,.up-row.fail .up-meta{color:#b91c1c}
/* buttons */
.up-btn{flex:none;display:inline-grid;place-items:center;min-width:34px;height:34px;padding:0 8px;border:0;border-radius:9px;
  background:transparent;color:var(--up-muted);font:inherit;font-size:.84rem;font-weight:600;cursor:pointer;transition:background-color .15s,color .15s}
.up-btn:hover{background:#eef2f8;color:var(--up-ink)}
.up-btn:focus-visible{outline:2px solid var(--up-accent);outline-offset:2px}
.up-btn.text{color:var(--up-accent)}
.up-btn svg{width:16px;height:16px}
/* download card */
.up-dl{display:grid;grid-template-columns:minmax(0,1fr);gap:12px}
.up-dl-top{display:flex;align-items:center;gap:14px}
.up-dl-icon{flex:none;display:grid;place-items:center;width:44px;height:44px;border-radius:12px;background:#dbeafe;color:#1d4ed8}
.up-dl-icon svg{width:22px;height:22px}
.up-dl-name{flex:1;min-width:0}
.up-dl-name b{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.up-dl .up-bar{height:8px}
.up-dl-foot{display:flex;flex-wrap:wrap;justify-content:space-between;gap:4px 12px;font-size:.8rem;color:var(--up-muted);font-variant-numeric:tabular-nums}
.up-dl-foot strong{color:var(--up-ink)}
.up-actions{display:flex;gap:4px}
/* toast: the bar runs along the bottom edge */
.up-toast{position:relative;display:flex;align-items:center;gap:12px;max-width:380px;margin:0 auto;padding:14px 14px 17px 16px;
  border-radius:12px;background:#fff;border:1px solid #dfe5ef;box-shadow:0 10px 30px -8px rgba(15,27,45,.25);overflow:hidden}
.up-toast>div{flex:1;min-width:0;font-size:.88rem}
.up-toast b{display:block;font-weight:600}
.up-toast span{font-size:.8rem;color:var(--up-muted)}
.up-toast .up-bar{position:absolute;left:0;right:0;bottom:0;height:3px;border-radius:0}
.up-toast .up-bar>i{border-radius:0 3px 3px 0}
@media (prefers-reduced-motion:reduce){.up-bar>i,.up-btn{transition:none}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div><span class="lbl">Upload queue</span><div class="card demo-card"><div class="card-body p-4">
<div class="up">
  <div class="d-flex justify-content-between align-items-baseline gap-3 mb-1"><b>Uploading 3 files</b><span class="small up-muted">1 of 3 done</span></div>
  <ul class="list-unstyled mb-0">
    <li class="up-row d-flex align-items-center gap-3">
      <span class="up-file pdf d-grid flex-shrink-0" style="place-items:center" aria-hidden="true">PDF</span>
      <div class="up-body d-grid flex-grow-1" style="min-width:0">
        <div class="up-top d-flex justify-content-between gap-2"><b class="fw-semibold text-truncate" id="up-f1">brand-guidelines-2026.pdf</b><span class="fw-bold flex-shrink-0" aria-hidden="true">62%</span></div>
        <div class="progress" role="progressbar" aria-labelledby="up-f1" aria-valuenow="62" aria-valuemin="0" aria-valuemax="100" aria-valuetext="62%, 4.2 MB of 6.8 MB"><div class="progress-bar" style="width:62%"></div></div>
        <div class="up-meta">4.2 MB of 6.8 MB · 8 seconds left</div>
      </div>
      <button class="btn flex-shrink-0" type="button" aria-label="Cancel upload of brand-guidelines-2026.pdf"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 5l10 10M15 5 5 15"/></svg></button>
    </li>
    <li class="up-row d-flex align-items-center gap-3">
      <span class="up-file jpg d-grid flex-shrink-0" style="place-items:center" aria-hidden="true">JPG</span>
      <div class="up-body d-grid flex-grow-1" style="min-width:0">
        <div class="up-top d-flex justify-content-between gap-2"><b class="fw-semibold text-truncate" id="up-f2">hero-shot-final.jpg</b><span class="fw-bold flex-shrink-0 text-success" aria-hidden="true">Done</span></div>
        <div class="progress" role="progressbar" aria-labelledby="up-f2" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" aria-valuetext="Uploaded, 3.1 MB"><div class="progress-bar bg-success" style="width:100%"></div></div>
        <div class="up-meta">3.1 MB · Uploaded</div>
      </div>
      <button class="btn flex-shrink-0" type="button" aria-label="Remove hero-shot-final.jpg"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h12M8 6V4h4v2M6 6l1 10h6l1-10"/></svg></button>
    </li>
    <li class="up-row d-flex align-items-center gap-3">
      <span class="up-file mov d-grid flex-shrink-0" style="place-items:center" aria-hidden="true">MOV</span>
      <div class="up-body d-grid flex-grow-1" style="min-width:0">
        <div class="up-top d-flex justify-content-between gap-2"><b class="fw-semibold text-truncate" id="up-f3">product-demo-v3.mov</b><span class="fw-bold flex-shrink-0 text-danger" aria-hidden="true">Failed</span></div>
        <div class="progress" role="progressbar" aria-labelledby="up-f3" aria-valuenow="38" aria-valuemin="0" aria-valuemax="100" aria-valuetext="Failed at 38%, connection lost"><div class="progress-bar bg-danger" style="width:38%"></div></div>
        <div class="up-meta text-danger">Connection lost at 18.4 MB of 48.2 MB</div>
      </div>
      <button class="btn up-text flex-shrink-0" type="button" aria-label="Retry upload of product-demo-v3.mov">Retry</button>
    </li>
  </ul>
</div></div></div></div>

<div><span class="lbl">Download with pause and cancel</span><div class="card demo-card"><div class="card-body p-4">
<div class="up up-dl d-grid gap-3">
  <div class="d-flex align-items-center gap-3">
    <span class="up-dl-icon d-grid flex-shrink-0" style="place-items:center" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4v11M7 10l5 5 5-5M5 20h14"/></svg></span>
    <div class="flex-grow-1" style="min-width:0"><b class="d-block text-truncate" id="up-dl">Figma-126.4-arm64.dmg</b><span class="up-meta">From figma.com · 2.4 MB/s</span></div>
    <div class="d-flex gap-1">
      <button class="btn" type="button" aria-label="Pause download of Figma-126.4-arm64.dmg"><svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><rect x="5" y="4" width="3.5" height="12" rx="1"/><rect x="11.5" y="4" width="3.5" height="12" rx="1"/></svg></button>
      <button class="btn" type="button" aria-label="Cancel download of Figma-126.4-arm64.dmg"><svg viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 5l10 10M15 5 5 15"/></svg></button>
    </div>
  </div>
  <div class="progress" role="progressbar" aria-labelledby="up-dl" aria-valuenow="59" aria-valuemin="0" aria-valuemax="100" aria-valuetext="59%, 184 MB of 312 MB, about 53 seconds left"><div class="progress-bar" style="width:59%"></div></div>
  <div class="up-meta d-flex flex-wrap justify-content-between column-gap-3 row-gap-1"><span><strong>184 MB</strong> of 312 MB</span><span>About 53 seconds left</span></div>
</div></div></div></div>

<div><span class="lbl">Toast with an edge bar</span><div class="card demo-card"><div class="card-body p-4">
<div class="up toast show mx-auto">
  <div class="toast-body d-flex align-items-center gap-3">
    <div class="flex-grow-1" style="min-width:0"><b class="d-block fw-semibold" id="up-toast">Uploading 2 of 5 photos</b><span class="up-meta">40% · Lake Bled album</span></div>
    <button class="btn up-text" type="button" aria-label="Cancel uploading photos to Lake Bled album">Cancel</button>
  </div>
  <div class="progress" role="progressbar" aria-labelledby="up-toast" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"><div class="progress-bar" style="width:40%"></div></div>
</div></div></div></div>
CSS
/* Upload and download rows on Bootstrap .progress, .btn and .toast. Each .progress is role="progressbar" labelled by
   the file name, with the size in aria-valuetext. The buttons name the file they act on. Wire them to your uploader. */
.up{--up-accent:#2563eb;--up-track:#e3e8f0;--up-ink:#0f1b2d;--up-muted:#56627a;
  --bs-success-rgb:21,128,61;--bs-danger-rgb:185,28,28;color:var(--up-ink)}
.up .progress{--bs-progress-height:6px;--bs-progress-bg:var(--up-track);--bs-progress-bar-bg:var(--up-accent);
  --bs-progress-border-radius:999px;--bs-progress-bar-transition:width .3s linear}
.up .progress-bar{border-radius:inherit}
.up .progress-bar.bg-danger{background-color:#dc2626!important}
.up .up-muted{color:var(--up-muted)}
.up .up-row{padding:14px 0;border-top:1px solid #edf1f6}
.up .up-row:first-child{border-top:0}
.up .up-row:last-child{padding-bottom:0}
.up .up-file{width:38px;height:44px;border-radius:8px;font-size:.62rem;font-weight:800;letter-spacing:.04em}
.up .up-file.pdf{background:#fee2e2;color:#b91c1c}
.up .up-file.jpg{background:#ede9fe;color:#6d28d9}
.up .up-file.mov{background:#dbeafe;color:#1d4ed8}
.up .up-body{grid-template-columns:minmax(0,1fr);gap:7px}
.up .up-top{font-size:.9rem}
.up .up-meta{font-size:.8rem;color:var(--up-muted);font-variant-numeric:tabular-nums}
.up .up-meta strong{color:var(--up-ink)}
/* buttons: ghost .btn with the icon or a short word */
.up .btn{--bs-btn-padding-x:8px;--bs-btn-padding-y:0;--bs-btn-font-size:.84rem;--bs-btn-font-weight:600;--bs-btn-border-width:0;
  --bs-btn-border-radius:9px;--bs-btn-color:var(--up-muted);--bs-btn-hover-color:var(--up-ink);--bs-btn-hover-bg:#eef2f8;
  --bs-btn-active-color:var(--up-ink);--bs-btn-active-bg:#e3e8f0;display:inline-grid;place-items:center;min-width:34px;height:34px}
.up .btn.up-text{--bs-btn-color:var(--up-accent);--bs-btn-hover-color:var(--up-accent)}
.up .btn:focus-visible{outline:2px solid var(--up-accent);outline-offset:2px;box-shadow:none}
.up .btn svg{width:16px;height:16px}
/* download card */
.up .up-dl-icon{width:44px;height:44px;border-radius:12px;background:#dbeafe;color:#1d4ed8}
.up .up-dl-icon svg{width:22px;height:22px}
.up.up-dl{grid-template-columns:minmax(0,1fr)}
.up.up-dl .progress{--bs-progress-height:8px}
/* toast: the bar runs along the bottom edge */
.up.toast{--bs-toast-max-width:380px;--bs-toast-border-color:#dfe5ef;--bs-toast-border-radius:12px;
  --bs-toast-box-shadow:0 10px 30px -8px rgba(15,27,45,.25);--bs-toast-font-size:.88rem;position:relative;overflow:hidden}
.up.toast .toast-body{padding:14px 14px 17px 16px}
.up.toast .progress{position:absolute;left:0;right:0;bottom:0;--bs-progress-height:3px;--bs-progress-border-radius:0}
.up.toast .progress-bar{border-radius:0 3px 3px 0}
@media (prefers-reduced-motion:reduce){.up .progress-bar,.up .btn{transition:none}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div><span class="mb-3 block text-[.72rem] tracking-[.12em] text-up-muted uppercase">Upload queue</span><div class="rounded-2xl border border-[#dfe5ef] bg-white px-6 pt-[22px] pb-6 shadow-[0_1px_2px_rgba(15,27,45,.04)]">
<div>
  <div class="mb-1.5 flex items-baseline justify-between gap-3"><b>Uploading 3 files</b><span class="text-[.84rem] text-up-muted">1 of 3 done</span></div>
  <ul>
    <li class="flex items-center gap-3.5 pt-3.5 pb-3.5">
      <span class="grid h-11 w-[38px] flex-none place-items-center rounded-lg bg-[#fee2e2] text-[.62rem] font-extrabold tracking-[.04em] text-[#b91c1c]" aria-hidden="true">PDF</span>
      <div class="grid min-w-0 flex-1 grid-cols-[minmax(0,1fr)] gap-[7px]">
        <div class="flex justify-between gap-2.5 text-[.9rem]"><b class="min-w-0 truncate font-semibold" id="up-f1">brand-guidelines-2026.pdf</b><span class="flex-none font-bold tabular-nums" aria-hidden="true">62%</span></div>
        <div class="h-1.5 overflow-hidden rounded-full bg-up-track" role="progressbar" aria-labelledby="up-f1" aria-valuenow="62" aria-valuemin="0" aria-valuemax="100" aria-valuetext="62%, 4.2 MB of 6.8 MB"><div class="h-full w-[62%] rounded-full bg-up-accent transition-[width] duration-300 ease-linear motion-reduce:transition-none"></div></div>
        <div class="text-[.8rem] text-up-muted tabular-nums">4.2 MB of 6.8 MB · 8 seconds left</div>
      </div>
      <button class="grid h-[34px] min-w-[34px] flex-none cursor-pointer place-items-center rounded-[9px] px-2 text-up-muted transition-colors hover:bg-up-hover hover:text-up-ink focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-up-accent motion-reduce:transition-none" type="button" aria-label="Cancel upload of brand-guidelines-2026.pdf"><svg class="size-4" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 5l10 10M15 5 5 15"/></svg></button>
    </li>
    <li class="flex items-center gap-3.5 border-t border-up-line py-3.5">
      <span class="grid h-11 w-[38px] flex-none place-items-center rounded-lg bg-[#ede9fe] text-[.62rem] font-extrabold tracking-[.04em] text-[#6d28d9]" aria-hidden="true">JPG</span>
      <div class="grid min-w-0 flex-1 grid-cols-[minmax(0,1fr)] gap-[7px]">
        <div class="flex justify-between gap-2.5 text-[.9rem]"><b class="min-w-0 truncate font-semibold" id="up-f2">hero-shot-final.jpg</b><span class="flex-none font-bold text-up-ok" aria-hidden="true">Done</span></div>
        <div class="h-1.5 overflow-hidden rounded-full bg-up-track" role="progressbar" aria-labelledby="up-f2" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" aria-valuetext="Uploaded, 3.1 MB"><div class="h-full w-full rounded-full bg-up-ok"></div></div>
        <div class="text-[.8rem] text-up-muted tabular-nums">3.1 MB · Uploaded</div>
      </div>
      <button class="grid h-[34px] min-w-[34px] flex-none cursor-pointer place-items-center rounded-[9px] px-2 text-up-muted transition-colors hover:bg-up-hover hover:text-up-ink focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-up-accent motion-reduce:transition-none" type="button" aria-label="Remove hero-shot-final.jpg"><svg class="size-4" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h12M8 6V4h4v2M6 6l1 10h6l1-10"/></svg></button>
    </li>
    <li class="flex items-center gap-3.5 border-t border-up-line pt-3.5">
      <span class="grid h-11 w-[38px] flex-none place-items-center rounded-lg bg-[#dbeafe] text-[.62rem] font-extrabold tracking-[.04em] text-[#1d4ed8]" aria-hidden="true">MOV</span>
      <div class="grid min-w-0 flex-1 grid-cols-[minmax(0,1fr)] gap-[7px]">
        <div class="flex justify-between gap-2.5 text-[.9rem]"><b class="min-w-0 truncate font-semibold" id="up-f3">product-demo-v3.mov</b><span class="flex-none font-bold text-up-bad-text" aria-hidden="true">Failed</span></div>
        <div class="h-1.5 overflow-hidden rounded-full bg-up-track" role="progressbar" aria-labelledby="up-f3" aria-valuenow="38" aria-valuemin="0" aria-valuemax="100" aria-valuetext="Failed at 38%, connection lost"><div class="h-full w-[38%] rounded-full bg-up-bad"></div></div>
        <div class="text-[.8rem] text-up-bad-text tabular-nums">Connection lost at 18.4 MB of 48.2 MB</div>
      </div>
      <button class="grid h-[34px] min-w-[34px] flex-none cursor-pointer place-items-center rounded-[9px] px-2 text-[.84rem] font-semibold text-up-accent transition-colors hover:bg-up-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-up-accent motion-reduce:transition-none" type="button" aria-label="Retry upload of product-demo-v3.mov">Retry</button>
    </li>
  </ul>
</div></div></div>

<div><span class="mb-3 block text-[.72rem] tracking-[.12em] text-up-muted uppercase">Download with pause and cancel</span><div class="rounded-2xl border border-[#dfe5ef] bg-white px-6 pt-[22px] pb-6 shadow-[0_1px_2px_rgba(15,27,45,.04)]">
<div class="grid grid-cols-[minmax(0,1fr)] gap-3">
  <div class="flex items-center gap-3.5">
    <span class="grid size-11 flex-none place-items-center rounded-xl bg-[#dbeafe] text-[#1d4ed8]" aria-hidden="true"><svg class="size-[22px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 4v11M7 10l5 5 5-5M5 20h14"/></svg></span>
    <div class="min-w-0 flex-1"><b class="block truncate" id="up-dl">Figma-126.4-arm64.dmg</b><span class="text-[.8rem] text-up-muted">From figma.com · 2.4 MB/s</span></div>
    <div class="flex gap-1">
      <button class="grid h-[34px] min-w-[34px] cursor-pointer place-items-center rounded-[9px] px-2 text-up-muted transition-colors hover:bg-up-hover hover:text-up-ink focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-up-accent motion-reduce:transition-none" type="button" aria-label="Pause download of Figma-126.4-arm64.dmg"><svg class="size-4" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><rect x="5" y="4" width="3.5" height="12" rx="1"/><rect x="11.5" y="4" width="3.5" height="12" rx="1"/></svg></button>
      <button class="grid h-[34px] min-w-[34px] cursor-pointer place-items-center rounded-[9px] px-2 text-up-muted transition-colors hover:bg-up-hover hover:text-up-ink focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-up-accent motion-reduce:transition-none" type="button" aria-label="Cancel download of Figma-126.4-arm64.dmg"><svg class="size-4" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M5 5l10 10M15 5 5 15"/></svg></button>
    </div>
  </div>
  <div class="h-2 overflow-hidden rounded-full bg-up-track" role="progressbar" aria-labelledby="up-dl" aria-valuenow="59" aria-valuemin="0" aria-valuemax="100" aria-valuetext="59%, 184 MB of 312 MB, about 53 seconds left"><div class="h-full w-[59%] rounded-full bg-up-accent transition-[width] duration-300 ease-linear motion-reduce:transition-none"></div></div>
  <div class="flex flex-wrap justify-between gap-x-3 gap-y-1 text-[.8rem] text-up-muted tabular-nums"><span><strong class="text-up-ink">184 MB</strong> of 312 MB</span><span>About 53 seconds left</span></div>
</div></div></div>

<div><span class="mb-3 block text-[.72rem] tracking-[.12em] text-up-muted uppercase">Toast with an edge bar</span><div class="rounded-2xl border border-[#dfe5ef] bg-white px-6 pt-[22px] pb-6 shadow-[0_1px_2px_rgba(15,27,45,.04)]">
<div class="relative mx-auto flex max-w-[380px] items-center gap-3 overflow-hidden rounded-xl border border-[#dfe5ef] bg-white pt-3.5 pr-3.5 pb-[17px] pl-4 shadow-[0_10px_30px_-8px_rgba(15,27,45,.25)]">
  <div class="min-w-0 flex-1 text-[.88rem]"><b class="block font-semibold" id="up-toast">Uploading 2 of 5 photos</b><span class="text-[.8rem] text-up-muted">40% · Lake Bled album</span></div>
  <button class="grid h-[34px] min-w-[34px] cursor-pointer place-items-center rounded-[9px] px-2 text-[.84rem] font-semibold text-up-accent transition-colors hover:bg-up-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-up-accent motion-reduce:transition-none" type="button" aria-label="Cancel uploading photos to Lake Bled album">Cancel</button>
  <div class="absolute inset-x-0 bottom-0 h-[3px] bg-up-track" role="progressbar" aria-labelledby="up-toast" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"><div class="h-full w-[40%] rounded-r-[3px] bg-up-accent transition-[width] duration-300 ease-linear motion-reduce:transition-none"></div></div>
</div></div></div>
CSS
@theme {
  --color-up-accent: #2563eb;
  --color-up-ok: #15803d;
  --color-up-bad: #dc2626;
  --color-up-bad-text: #b91c1c;
  --color-up-track: #e3e8f0;
  --color-up-ink: #0f1b2d;
  --color-up-muted: #56627a;
  --color-up-line: #edf1f6;
  --color-up-hover: #eef2f8;
}

About this set

File transfer progress for upload forms, media libraries and download managers. Upload queue lists three files with a coloured file-type tile, the name, a bar, the size transferred and a button: the PDF is at 62 percent with a cancel button, the photo is done with a green bar and a remove button, and the video failed at 38 percent with the reason in red and a retry button. Long file names are cut with an ellipsis instead of pushing the button off the row. Download with pause and cancel is a single larger card with the file name, source and speed, pause and cancel icon buttons, a bar, and the amount and time left underneath. Toast with an edge bar is a compact notice for background uploads, with a 3 pixel bar along its bottom edge and a cancel button. Each bar is role=”progressbar” labelled by the file name, with the transferred size in aria-valuetext. The buttons are plain button elements with no script attached, so you wire them to your uploader; each one names its file, so a screen reader hears Cancel upload of brand-guidelines-2026.pdf rather than a row of identical Cancel buttons.

What’s included

  • Uploading, done and failed row states
  • Cancel, remove, retry and pause buttons that name their file
  • File names truncated with an ellipsis
  • Download card with speed and time left
  • Toast with a bar along its bottom edge
  • Bootstrap version uses .progress, .btn and .toast

Accessibility

Each bar is role="progressbar" labelled by its file name through aria-labelledby, with aria-valuetext such as 62%, 4.2 MB of 6.8 MB or failed at 38%, connection lost. Icon buttons have an aria-label that includes the file name, and text buttons such as Retry keep their visible word at the start of the label. Every button shows a 2 pixel outline on keyboard focus, and the bar and hover transitions are switched off under prefers-reduced-motion.

Customise it

Change --up-accent, --up-ok, --up-bad and --up-track on .up in the plain CSS and Bootstrap versions, where the buttons also take the --bs-btn-* variables. In Tailwind edit the up- theme colours.