Back to CSS Tags & Chips Remove with Undo Light JS
Share
.ctc-undo { position: relative; display: flex; flex-direction: column; gap: 12px; min-height: 70px; }

.ctc-undo-list { display: flex; flex-wrap: wrap; gap: 8px; }

.ctc-undo-chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 8px 6px 12px; background: #1f1f2e; color: #f0eeff; border: 1px solid rgba(255,255,255,0.08); border-radius: 999px; font: 600 12px/1 system-ui, sans-serif; transition: opacity 0.25s, transform 0.25s; }

.ctc-undo-chip.is-removing { opacity: 0; transform: scale(0.7); pointer-events: none; }

.ctc-undo-chip button { width: 18px; height: 18px; background: transparent; border: 0; padding: 0; color: #b8b6d4; cursor: pointer; font-size: 16px; line-height: 1; border-radius: 50%; }

.ctc-undo-chip button:hover { background: rgba(255,255,255,0.1); color: #fff; }

.ctc-undo-toast { display: inline-flex; align-items: center; gap: 12px; padding: 8px 12px; background: #15151d; border: 1px solid rgba(46,204,138,0.4); border-radius: 8px; font: 500 12px/1.2 system-ui, sans-serif; color: #c4b5fd; align-self: flex-start; animation: ctc-undo-in 0.2s ease; }

.ctc-undo-toast[hidden] { display: none; }

.ctc-undo-btn { background: transparent; border: 0; color: #2ecc8a; font: inherit; font-weight: 700; cursor: pointer; padding: 0; }

.ctc-undo-btn:hover { text-decoration: underline; }
<div class="ctc-undo">
  <div class="ctc-undo-list">
    <span class="ctc-undo-chip" data-ctc-undo>Frontend<button type="button" aria-label="Remove Frontend">×</button></span>
    <span class="ctc-undo-chip" data-ctc-undo>Backend<button type="button" aria-label="Remove Backend">×</button></span>
    <span class="ctc-undo-chip" data-ctc-undo>DevOps<button type="button" aria-label="Remove DevOps">×</button></span>
  </div>
  <div class="ctc-undo-toast" role="status" aria-live="polite" hidden>
    <span class="ctc-undo-msg"></span>
    <button type="button" class="ctc-undo-btn">Undo</button>
  </div>
</div>
(function () {
  document.querySelectorAll('.ctc-undo').forEach(function (root) {
    var toast = root.querySelector('.ctc-undo-toast');
    var msg   = root.querySelector('.ctc-undo-msg');
    var btn   = root.querySelector('.ctc-undo-btn');
    var pendingChip = null;
    var timer = null;
    function commit() {
      if (pendingChip && pendingChip.parentNode) pendingChip.parentNode.removeChild(pendingChip);
      pendingChip = null;
      toast.setAttribute('hidden','');
      timer = null;
    }
    btn.addEventListener('click', function () {
      if (!pendingChip) return;
      pendingChip.classList.remove('is-removing');
      clearTimeout(timer); timer = null;
      pendingChip = null;
      toast.setAttribute('hidden','');
    });
    root.querySelectorAll('[data-ctc-undo] button').forEach(function (x) {
      x.addEventListener('click', function () {
        if (timer) commit();
        var chip = x.closest('[data-ctc-undo]');
        chip.classList.add('is-removing');
        pendingChip = chip;
        msg.textContent = 'Removed "' + chip.firstChild.textContent.trim() + '"';
        toast.removeAttribute('hidden');
        timer = setTimeout(commit, 4000);
      });
    });
  });
})();
Live preview Edit any tab — preview updates live Ready