18 CSS Close Buttons

Hold to Confirm

A safety net for destructive actions — press and hold for 800ms while the ring fills clockwise, release early to cancel. Releases on full ring.

CSS + JS MIT licensed

Hold to Confirm the 14th of 18 designs in the 18 CSS Close Buttons 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="ccb-hold" aria-label="Hold to close">
  <svg viewBox="0 0 40 40" class="ccb-hold-ring"><circle cx="20" cy="20" r="18" /></svg><span></span
  ><span></span>
</button>
.ccb-hold {
  width: 40px; height: 40px;
  border: none; border-radius: 50%;
  background: rgba(255,108,138,0.12);
  position: relative; cursor: pointer;
  transition: background 0.2s;
}
.ccb-hold:hover { background: rgba(255,108,138,0.2); }
.ccb-hold-ring {
  position: absolute; inset: 0; width: 100%; height: 100%;
  transform: rotate(-90deg); pointer-events: none;
}
.ccb-hold-ring circle {
  fill: none; stroke: #ff6c8a; stroke-width: 2;
  stroke-dasharray: 113; stroke-dashoffset: 113;
  transition: stroke-dashoffset 0.05s linear;
}
.ccb-hold.is-holding .ccb-hold-ring circle {
  transition: stroke-dashoffset 0.8s linear;
  stroke-dashoffset: 0;
}
.ccb-hold span {
  position: absolute; top: 50%; left: 50%;
  width: 14px; height: 2px;
  background: #ff6c8a; border-radius: 2px;
}
.ccb-hold span:nth-child(2) { transform: translate(-50%,-50%) rotate(45deg); }
.ccb-hold span:nth-child(3) { transform: translate(-50%,-50%) rotate(-45deg); }
.ccb-hold.is-confirmed { background: rgba(46,204,138,0.25); transform: scale(1.1); }
.ccb-hold.is-confirmed span { background: #2ecc8a; }
.ccb-hold.is-confirmed .ccb-hold-ring circle { stroke: #2ecc8a; }
document.querySelectorAll('.ccb-hold').forEach(function(btn) {
  var timer;
  function start() {
    btn.classList.add('is-holding');
    timer = setTimeout(function() {
      btn.classList.remove('is-holding');
      btn.classList.add('is-confirmed');
      setTimeout(function() { btn.classList.remove('is-confirmed'); }, 600);
    }, 800);
  }
  function cancel() {
    clearTimeout(timer);
    btn.classList.remove('is-holding');
  }
  btn.addEventListener('mousedown', start);
  btn.addEventListener('touchstart', start, { passive: true });
  btn.addEventListener('mouseup',    cancel);
  btn.addEventListener('mouseleave', cancel);
  btn.addEventListener('touchend',   cancel);
});

Search CodeFronts

Loading…