43 CSS Button Designs

Like Heart

A toggle that bursts seven floating heart particles upward on activation; the count ticks up or down with a sliding number animation.

CSS + JS MIT licensed

Like Heart the 3rd 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

Open in playground

The code

<button class="btn-like" aria-pressed="false">
  <span class="btn-like-heart" aria-hidden="true">🤍</span>
  <span class="btn-like-count">2.4k</span>
</button>
.btn-like {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 22px;
  border: 1.5px solid #e0dbd3;
  border-radius: 50px;
  background: transparent;
  cursor: pointer;
  overflow: visible;
  user-select: none;
  transition: border-color 0.3s, background 0.3s;
}
.btn-like:hover { border-color: #f43f5e; background: #fff0f3; }
.btn-like-heart {
  font-size: 22px;
  line-height: 1;
  filter: grayscale(1);
  transition: transform 0.15s cubic-bezier(.34,1.56,.64,1);
}
.btn-like-count {
  display: flex;
  align-items: center;
  height: 20px;
  min-width: 24px;
  overflow: hidden;
  font-family: ui-sans-serif, system-ui, sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: #888;
  transition: color 0.3s;
}
.btn-like.is-liked { border-color: #f43f5e; background: #fff0f3; }
.btn-like.is-liked .btn-like-heart {
  filter: none;
  animation: btn-like-pop 0.4s cubic-bezier(.34,1.56,.64,1) forwards;
}
.btn-like.is-liked .btn-like-count { color: #f43f5e; }
@keyframes btn-like-pop {
  0%   { transform: scale(0.8); }
  50%  { transform: scale(1.4); }
  100% { transform: scale(1); }
}
.btn-like-particle {
  position: absolute;
  font-size: var(--fs, 12px);
  line-height: 1;
  pointer-events: none;
  z-index: 10;
  animation: btn-like-fly 0.7s cubic-bezier(.22,1,.36,1) forwards;
}
@keyframes btn-like-fly {
  0%   { transform: translate(0,0) scale(1); opacity: 1; }
  100% { transform: translate(var(--tx), var(--ty)) scale(0.3); opacity: 0; }
}
.btn-like-slide {
  display: inline-block;
  animation: btn-like-count-up 0.3s cubic-bezier(.22,1,.36,1) forwards;
}
@keyframes btn-like-count-up {
  from { transform: translateY(100%); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .btn-like-heart, .btn-like-slide, .btn-like-particle { animation: none; }
}
document.querySelectorAll('.btn-like').forEach(function (btn) {
  var liked = false;
  var count = 2400;
  var heart = btn.querySelector('.btn-like-heart');
  var label = btn.querySelector('.btn-like-count');
  btn.addEventListener('click', function () {
    liked = !liked;
    btn.classList.toggle('is-liked', liked);
    btn.setAttribute('aria-pressed', String(liked));
    heart.textContent = liked ? '❤️' : '🤍';
    count += liked ? 1 : -1;
    var text = count >= 1000 ? (count / 1000).toFixed(1) + 'k' : String(count);
    var span = document.createElement('span');
    span.className = 'btn-like-slide';
    span.textContent = text;
    label.innerHTML = '';
    label.appendChild(span);
    if (liked) {
      var cx = heart.offsetLeft + heart.offsetWidth / 2;
      var cy = heart.offsetTop + heart.offsetHeight / 2;
      for (var i = 0; i < 7; i++) {
        var p = document.createElement('span');
        p.className = 'btn-like-particle';
        p.textContent = '❤️';
        var angle = -Math.PI / 2 + (Math.random() - 0.5) * Math.PI * 1.5;
        var dist = 25 + Math.random() * 35;
        p.style.left = cx + 'px';
        p.style.top = cy + 'px';
        p.style.setProperty('--tx', (Math.cos(angle) * dist) + 'px');
        p.style.setProperty('--ty', (Math.sin(angle) * dist) + 'px');
        p.style.setProperty('--fs', (9 + Math.random() * 7) + 'px');
        p.style.animationDelay = (Math.random() * 0.15) + 's';
        btn.appendChild(p);
        p.addEventListener('animationend', function () { this.remove(); });
      }
    }
  });
});

Search CodeFronts

Loading…