Full Source Code — Epic Animated Delete Button
HTML
CSS
JavaScript
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Epic Animated Delete Button</title> <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@800&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"> </head> <body> <div class="delete-container"> <button class="delete-btn" id="deleteBtn"> <i class="fas fa-trash-alt"></i> Delete </button> </div> </body> </html>
/* ── BACKGROUND ───────────────────────────────────────────── */
body {
margin: 0; height: 100vh;
background: linear-gradient(135deg, #1e1e2f, #2d1b3a); /* Dark purple gradient */
display: flex; justify-content: center; align-items: center;
font-family: 'Montserrat', sans-serif;
overflow: hidden; /* Prevents confetti from creating scrollbars */
}
.delete-container { position: relative; }
/* ── BUTTON BASE ──────────────────────────────────────────── */
.delete-btn {
padding: 20px 54px;
font-size: 22px; font-weight: 800;
color: white;
background: linear-gradient(45deg, #ff3b30, #ff2d55); /* Red-to-pink gradient */
border: none;
border-radius: 60px; /* Pill shape */
cursor: pointer;
text-transform: uppercase;
letter-spacing: 3px;
box-shadow: 0 15px 35px rgba(255, 45, 80, 0.5); /* Red glow shadow */
/* cubic-bezier(0.68, -0.55, 0.27, 1.55) = elastic overshoot: */
/* y1 = -0.55 causes initial backward motion before forward leap */
/* y2 = 1.55 causes forward overshoot past target before settling */
transition: all 0.4s cubic-bezier(0.68, -0.55, 0.27, 1.55);
position: relative; overflow: hidden; z-index: 10;
}
.delete-btn i {
margin-right: 14px; font-size: 26px; /* Trash icon — larger than text */
}
/* ── HOVER STATE (Elastic Lift) ───────────────────────────── */
.delete-btn:hover {
transform: scale(1.1) translateY(-10px); /* 10% larger + lift 10px */
box-shadow: 0 25px 50px rgba(255, 45, 80, 0.7); /* Stronger glow when lifted */
}
/* ── SHRED ANIMATION ──────────────────────────────────────── */
/* Triggered by JS adding the 'shred' class on confirm */
.shred { animation: shred 1.2s ease-in forwards; }
@keyframes shred {
0% { transform: translateY(0) rotate(0); opacity: 1; }
/* 50% jolt: brief downward catch before the full fall — adds physical weight */
50% { transform: translateY(20px) rotate(5deg); }
/* 100%: falls off-screen, spins 3× (1080deg), shrinks to 10%, fades out */
100%{ transform: translateY(100vh) rotate(1080deg) scale(0.1); opacity: 0; }
}
/* ── CONFETTI PARTICLES (created dynamically by JS) ──────── */
.confetti {
position: absolute;
width: 10px; height: 10px;
background: #ff006e; /* Default — overridden by JS inline style */
border-radius: 2px; /* Slightly rounded square */
animation: confetti-fall linear forwards;
pointer-events: none; /* Doesn't block clicks or hover */
}
@keyframes confetti-fall {
0% { transform: translateY(-100vh) rotate(0deg); opacity: 1; }
100%{ transform: translateY(100vh) rotate(720deg); opacity: 0; }
/* Falls from above viewport to below viewport while spinning twice */
}
const btn = document.getElementById('deleteBtn');
btn.addEventListener('click', function() {
// ── CONFIRMATION GATE ──────────────────────────────────────
// confirm() is synchronous — blocks until user clicks OK or Cancel
// Returns true (OK) or false (Cancel)
// !false = true → return early (cancel the delete)
if (!confirm("Are you absolutely sure? This cannot be undone!")) return;
// ── TRIGGER SHRED ANIMATION ────────────────────────────────
// Adding 'shred' class applies the @keyframes shred animation
btn.classList.add('shred');
// ── CONFETTI EXPLOSION (80 particles) ────────────────────
for (let i = 0; i < 80; i++) {
const confetti = document.createElement('div'); // Create particle element
confetti.classList.add('confetti'); // Apply fall animation CSS
// Random color from the warm red/orange palette array
// Math.floor(Math.random() * 5) → uniform integer 0–4
confetti.style.background = [
'#ff006e', '#ff5e3a', '#ff2d55', '#ff9500', '#ff1744'
][Math.floor(Math.random() * 5)];
confetti.style.left = Math.random() * 100 + 'vw'; // 0–100% of viewport width
confetti.style.top = Math.random() * 100 + 'vh'; // 0–100% of viewport height
confetti.style.animationDuration = (Math.random() * 3 + 2) + 's'; // 2–5 seconds
confetti.style.animationDelay = Math.random() * 0.5 + 's'; // 0–0.5s stagger
document.body.appendChild(confetti); // Inject particle into live page
// Clean up DOM after animation completes — prevents memory accumulation
setTimeout(() => confetti.remove(), 5000);
}
// ── COMPLETION SEQUENCE ────────────────────────────────────
setTimeout(() => {
alert("Deleted forever! Gone. Poof. Bye-bye."); // Final feedback
// Reset button to idle state so it can be clicked again
btn.classList.remove('shred'); // Remove animation class
btn.style.transform = ''; // Clear any inline transform
btn.style.opacity = '1'; // Ensure fully visible
}, 1500); // 1500ms = after shred animation reaches off-screen
});