Master Code
On The Go

Learn. Practice. Build.

UI Snippet

⬇️ Animated Download Button

A modern download button with progress bar, idle shimmer, and success state. Pure HTML, CSS, and JavaScript — no libraries.

🔍 Live Demo

Click any button below to see the animation. Each has a different style.

Gradient Button

Outline Style

Terminal Style

📘 What happens when you click
1. Button enters downloading state
2. Progress bar fills from 0% → 100%
3. Label updates to "Downloading… 45%"
4. On completion, button flips to a green done state
5. After 2 seconds, resets back to idle

💻 Complete Code

<!-- HTML -->
<button class="dl-btn" onclick="runDownload(this)">
    <span class="progress"></span>
    <span class="icon"><i class="fas fa-download"></i></span>
    <span class="label">Download File</span>
</button>

<!-- CSS -->
.dl-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    min-width: 220px;
    height: 56px;
    padding: 0 2rem;
    background: linear-gradient(135deg, #3b82f6, #8b5cf6);
    color: #fff;
    font-weight: 600;
    border: none;
    border-radius: 999px;
    cursor: pointer;
    overflow: hidden;
    transition: transform 0.2s ease, box-shadow 0.3s ease;
    box-shadow: 0 8px 20px -8px rgba(59,130,246,0.6);
}
.dl-btn:hover:not(:disabled) {
    transform: translateY(-2px);
    box-shadow: 0 14px 28px -10px rgba(139,92,246,0.7);
}

/* Shimmer sweep on hover */
.dl-btn::before {
    content: "";
    position: absolute;
    top: 0; left: -100%;
    width: 60%; height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.35), transparent);
    transition: left 0.6s ease;
}
.dl-btn:hover:not(:disabled)::before { left: 130%; }

/* Progress fill */
.dl-btn .progress {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 0%;
    background: rgba(255,255,255,0.25);
    transition: width 0.15s linear;
}

/* Content above progress */
.dl-btn .label,
.dl-btn .icon { position: relative; z-index: 1; }

/* Downloading state */
.dl-btn.downloading .icon { animation: bounce-arrow 1s infinite; }
@keyframes bounce-arrow {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(4px); }
}

/* Done state */
.dl-btn.done {
    background: linear-gradient(135deg, #22c55e, #16a34a);
    box-shadow: 0 8px 20px -8px rgba(34,197,94,0.6);
}
.dl-btn.done .icon { animation: pop 0.4s ease; }
@keyframes pop {
    0%   { transform: scale(0.6); }
    60%  { transform: scale(1.25); }
    100% { transform: scale(1); }
}

<!-- JavaScript -->
function runDownload(btn) {
    if (btn.classList.contains('downloading') || btn.classList.contains('done')) return;

    const progress = btn.querySelector('.progress');
    const label    = btn.querySelector('.label');
    const icon     = btn.querySelector('.icon');
    const originalLabel = label.textContent;
    const originalIcon  = icon.innerHTML;

    btn.classList.add('downloading');
    icon.innerHTML = '<i class="fas fa-download"></i>';

    let pct = 0;
    const tick = setInterval(() => {
        pct += Math.random() * 12 + 4; // 4–16% per tick
        if (pct >= 100) {
            pct = 100;
            progress.style.width = '100%';
            label.textContent = 'Completed!';
            icon.innerHTML = '<i class="fas fa-check"></i>';
            btn.classList.remove('downloading');
            btn.classList.add('done');
            clearInterval(tick);

            setTimeout(() => {
                progress.style.width = '0%';
                label.textContent = originalLabel;
                icon.innerHTML = originalIcon;
                btn.classList.remove('done');
            }, 2000);
        } else {
            progress.style.width = pct + '%';
            label.textContent = `Downloading… ${Math.floor(pct)}%`;
        }
    }, 200);
}

🧠 How It Works

💡 Why This Snippet?

← Back to Snippets 🚀 Get Pro Pack ($7) →