Animated Download Button with Progress Bar by Coodeverse is a free animated download button UI component built with pure HTML, CSS, and vanilla JavaScript. Click the button to trigger a simulated progress bar animation with gradient shine sweeps, a success checkmark state, and real file download via the JavaScript Blob API. Features glassmorphism design with dark card styling and ARIA accessibility attributes. Zero external libraries. Full source code free at coodeverse.com/projects/animated-download-button.
📊States:4 (Idle/Prep/Progress/Success)
·
Effect:Gradient Shine + Glow
·
💾Download:JavaScript Blob API
·
A11y:ARIA + Keyboard
·
📦Libraries:Zero
Live Preview

Button State Reference

Every state, CSS class, and JavaScript event in the animated download button lifecycle.

● State 1
Idle / Default
Glassmorphism button with rgba background and subtle border. Hover applies translateY(-3px) and enhanced box-shadow. Icon and "Download" label visible.
CSS: .btn default styles
● State 2
Preparing / Shine
.pulse class triggers ::before glow sliding from left:-40% to left:120% via CSS transition. .shining class runs the @keyframes shine sweep on the .shine span. Label changes to "Preparing..."
JS: btn.classList.add('pulse','shining')
● State 3
Progress Bar Running
Recursive step() function using setTimeout (140–500ms random delay) adds a random 2–10% delta to progress p. bar.style.width updates each tick. .shining fires randomly ~25% of ticks for organic feel.
JS: bar.style.width = p + '%'
● State 4
Success + Download
.success class applies green background (rgba(16,185,129)) and border. .check SVG animates from scale(0) to scale(1) via CSS transition. Blob API generates and downloads demo-file.txt. All state resets after 2.5s.
JS: btn.classList.add('success') + Blob API
Full Source Code
// index.html — Animated Download Button
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Animated Download Button</title>
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet" />
  <link rel="stylesheet" href="style.css" />
</head>
<body>

  <div class="card" role="region" aria-label="Download demo">
    <h1>Animated Download Button</h1>
    <p>Click the button to simulate a download with progress, finish state, and a lively gradient animation.</p>

    <div class="download-wrap">

      <!-- Main button -->
      <button id="downloadBtn" class="btn" aria-live="polite">

        <!-- Download arrow icon -->
        <svg class="icon" viewBox="0 0 24 24" fill="none" aria-hidden="true">
          <path d="M12 3v12" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
          <path d="M8.5 10.5L12 14l3.5-3.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
          <path d="M21 21H3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" opacity="0.9"/>
        </svg>

        <span class="label">Download</span>

        <!-- Success checkmark icon -->
        <svg class="check" viewBox="0 0 24 24" fill="none" aria-hidden="true">
          <path d="M20 6L9 17l-5-5" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
        </svg>

        <span class="shine"></span>  <!-- Shine sweep -->
        <span class="bar" aria-hidden="true"></span>  <!-- Progress bar -->
      </button>

      <!-- Progress % + file info -->
      <div style="flex:1;display:flex;flex-direction:column">
        <div style="display:flex;align-items:center;justify-content:flex-end;gap:8px">
          <div id="percent" style="font-size:13px;color:var(--muted);min-width:40px;text-align:right">0%</div>
        </div>
        <div class="note">File: <strong>demo-file.txt</strong> — 14 KB</div>
      </div>

    </div>
  </div>

  <script src="script.js"></script>
</body>
</html>
// download_btn_faq

Animated Download Button — FAQ

How the progress bar, animations, and Blob download work.

Create a button with a .bar span absolutely positioned at the bottom (height: 4px, width: 0%, transition: width .2s linear). Use CSS custom properties for gradient coloring. In JavaScript, use a recursive step() function with setTimeout to randomly increment the bar's width from 0% to 100%. Add gradient shine via CSS @keyframes on a separate .shine span. On completion, add a success CSS class and use the Blob API to trigger a real file download.

Two techniques create the shine. The ::before pseudo-element creates a blurred ambient glow that slides from left:-40% to left:120% via CSS transition when .pulse is added. A separate .shine span uses @keyframes shine to sweep a white gradient from translateX(-130%) to translateX(130%) with skewX(-12deg) for a diagonal effect. JavaScript adds the .shining class periodically during progress for an organic shimmer feeling.

The simulateDownload function initializes running = true (prevents double-clicks) and calls a recursive step() via setTimeout. Each step adds a random 2–10% delta to p (capped at 100), then updates bar.style.width and percent.textContent. The delay before the next step is randomly 140–500ms, creating organic-looking uneven progress. When p hits 100, finishDownload() is called.

finishDownload() creates a Blob with generated text content, calls URL.createObjectURL(blob) to get a temporary URL, creates a hidden anchor element with href set to that URL and download='demo-file.txt', appends it to the body, clicks it programmatically, then removes the anchor and revokes the URL. This triggers a real browser file download with zero server or backend required — pure client-side JavaScript.

Yes. Replace the setTimeout simulation with XMLHttpRequest or fetch progress events. For XHR: xhr.onprogress = (e) => { if (e.lengthComputable) { const pct = (e.loaded / e.total) * 100; bar.style.width = pct + '%'; percent.textContent = Math.round(pct) + '%'; } }. The CSS, button structure, shine animation, success state styling, and reset logic all work identically with real download progress. The component is keyboard-accessible (Enter/Space) and uses ARIA aria-live for screen reader announcements.

Yes. This project teaches: CSS custom properties and glassmorphism styling, CSS @keyframes for the shine animation, JavaScript class-based state management (.pulse, .shining, .success), recursive setTimeout for animation control, the JavaScript Blob API for client-side file generation, DOM manipulation and inline style updates, and ARIA accessibility attributes (aria-live, aria-hidden). Download the full source code free from Coodeverse.

Master CSS & JavaScript.
Build Pro UI Components.

Free courses in JavaScript, Python, SQL, Kotlin, HTML, CSS, DSA. No account needed.

🟡 JavaScript 🐍 Python 🌐 HTML 🎨 CSS 🗄️ SQL 📊 DSA 🟣 Kotlin
Learn JavaScript Free Browse All Projects