Back to CSS Close Buttons Particle Burst CSS + JS
Share
HTML
<button class="ccb-burst" aria-label="Close">
  <span class="ccb-burst-x"></span><span class="ccb-burst-x"></span>
</button>
CSS
.ccb-burst {
  width: 40px; height: 40px;
  border: none; border-radius: 50%;
  background: #ff6c8a;
  box-shadow: 0 4px 18px rgba(255,108,138,0.4);
  position: relative; cursor: pointer;
  transition: transform 0.2s, box-shadow 0.2s;
}
.ccb-burst:hover { transform: scale(1.08); box-shadow: 0 6px 24px rgba(255,108,138,0.55); }
.ccb-burst-x {
  position: absolute; top: 50%; left: 50%;
  width: 16px; height: 2px;
  background: #fff; border-radius: 2px;
  transition: opacity 0.15s;
}
.ccb-burst-x:nth-child(1) { transform: translate(-50%,-50%) rotate(45deg); }
.ccb-burst-x:nth-child(2) { transform: translate(-50%,-50%) rotate(-45deg); }
.ccb-burst.is-burst .ccb-burst-x { opacity: 0; }
.ccb-burst-particle {
  position: absolute; top: 50%; left: 50%;
  width: 5px; height: 5px;
  background: #fff; border-radius: 50%;
  pointer-events: none;
  animation: ccb-particle 0.7s ease-out forwards;
}
@keyframes ccb-particle {
  0%   { transform: translate(-50%,-50%) rotate(var(--a)) translateX(0)    scale(1); opacity: 1; }
  100% { transform: translate(-50%,-50%) rotate(var(--a)) translateX(28px) scale(0); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ccb-burst,
  .ccb-burst * {
    animation: none !important;
  }
}
JS
document.querySelectorAll('.ccb-burst').forEach(function(btn) {
  btn.addEventListener('click', function() {
    if (btn.classList.contains('is-burst')) return;
    btn.classList.add('is-burst');
    for (var i = 0; i < 8; i++) {
      var p = document.createElement('span');
      p.className = 'ccb-burst-particle';
      p.style.setProperty('--a', (i * 45) + 'deg');
      btn.appendChild(p);
      (function(node) { setTimeout(function() { node.remove(); }, 700); })(p);
    }
    setTimeout(function() { btn.classList.remove('is-burst'); }, 700);
  });
});