Add to Cart
A real e-commerce state machine: click fills a green progress bar along the bottom edge, snaps to a success state with a particle burst, then auto-resets after two seconds.
Add to Cart the 1st of 43 designs in the 43 CSS Button Designs collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<div class="btn-cart-surface">
<button class="btn-cart">
<span class="btn-cart-icon" aria-hidden="true">🛒</span>
<span class="btn-cart-text">Add to Cart</span>
<span class="btn-cart-bar" aria-hidden="true"></span>
<span class="btn-cart-check">✓ Added!</span>
<span class="btn-cart-particles" aria-hidden="true"></span>
</button>
</div> .btn-cart-surface {
display: flex;
align-items: center;
justify-content: center;
padding: 32px 40px;
background: #f2efe9;
border-radius: 16px;
}
.btn-cart {
position: relative;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
min-width: 200px;
padding: 15px 30px;
border: none;
border-radius: 14px;
background: #1a1814;
color: #fff;
font-family: ui-sans-serif, system-ui, sans-serif;
font-size: 14px;
font-weight: 600;
cursor: pointer;
overflow: hidden;
user-select: none;
transition: background 0.3s ease, transform 0.15s ease;
}
.btn-cart:hover { background: #333; transform: translateY(-1px); }
.btn-cart:active { transform: scale(0.97); }
.btn-cart-icon { font-size: 18px; transition: transform 0.3s, opacity 0.3s; }
.btn-cart-text { transition: opacity 0.2s; }
.btn-cart-bar {
position: absolute;
left: 0; bottom: 0;
height: 3px;
width: 0%;
background: #4ade80;
border-radius: 0 0 14px 14px;
}
.btn-cart-check {
position: absolute;
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
font-weight: 600;
opacity: 0;
transform: translateY(20px);
transition: opacity 0.3s, transform 0.3s;
}
.btn-cart.is-loading { pointer-events: none; }
.btn-cart.is-loading .btn-cart-bar {
width: 100%;
transition: width 1.2s cubic-bezier(.4,0,.2,1);
}
.btn-cart.is-success { background: #16a34a; pointer-events: none; }
.btn-cart.is-success .btn-cart-icon,
.btn-cart.is-success .btn-cart-text { opacity: 0; transform: translateY(-10px); }
.btn-cart.is-success .btn-cart-check { opacity: 1; transform: translateY(0); }
.btn-cart-particles { position: absolute; inset: 0; pointer-events: none; overflow: visible; }
.btn-cart-particle {
position: absolute;
width: 6px; height: 6px;
border-radius: 50%;
background: #4ade80;
animation: btn-cart-pop 0.6s cubic-bezier(.22,1,.36,1) forwards;
}
@keyframes btn-cart-pop {
0% { transform: translate(0,0) scale(1); opacity: 1; }
100% { transform: translate(var(--tx), var(--ty)) scale(0); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
.btn-cart-bar, .btn-cart-icon, .btn-cart-text, .btn-cart-check { transition: none; }
} document.querySelectorAll('.btn-cart').forEach(function (btn) {
var busy = false;
btn.addEventListener('click', function () {
if (busy) return;
busy = true;
var bar = btn.querySelector('.btn-cart-bar');
var wrap = btn.querySelector('.btn-cart-particles');
btn.classList.add('is-loading');
setTimeout(function () {
btn.classList.remove('is-loading');
btn.classList.add('is-success');
var colors = ['#4ade80', '#86efac', '#bbf7d0'];
for (var i = 0; i < 12; i++) {
var p = document.createElement('div');
p.className = 'btn-cart-particle';
var angle = (i / 12) * Math.PI * 2;
var dist = 20 + Math.random() * 35;
p.style.left = (btn.offsetWidth / 2) + 'px';
p.style.top = (btn.offsetHeight / 2) + 'px';
p.style.setProperty('--tx', (Math.cos(angle) * dist) + 'px');
p.style.setProperty('--ty', (Math.sin(angle) * dist) + 'px');
p.style.background = colors[i % 3];
p.style.animationDelay = (Math.random() * 0.1) + 's';
wrap.appendChild(p);
p.addEventListener('animationend', function () { this.remove(); });
}
setTimeout(function () {
btn.classList.remove('is-success');
bar.style.transition = 'none';
bar.style.width = '0%';
requestAnimationFrame(function () {
bar.style.transition = '';
busy = false;
});
}, 2200);
}, 1400);
});
});