Source Code

<div class="container py-5">
  <div class="list-group bspop-list" style="max-width:420px" id="bspopList">
    <div class="list-group-item d-flex justify-content-between align-items-center">
      <span>Q3-financial-report.pdf</span>
      <button class="btn btn-sm btn-outline-danger bspop-trigger" type="button">Delete</button>
    </div>
    <div class="list-group-item d-flex justify-content-between align-items-center">
      <span>brand-guidelines.sketch</span>
      <button class="btn btn-sm btn-outline-danger bspop-trigger" type="button">Delete</button>
    </div>
    <div class="list-group-item d-flex justify-content-between align-items-center">
      <span>onboarding-notes.docx</span>
      <button class="btn btn-sm btn-outline-danger bspop-trigger" type="button">Delete</button>
    </div>
  </div>
  <p class="text-muted small mt-3">Deleted: <strong id="bspopDeleted">none</strong></p>
</div>

Bootstrap Popover Confirm Delete — Free Snippet

Bootstrap Popover Confirm Delete · Buttons · Plain HTML, CSS & JS · Live preview

What's included

Features

Real Bootstrap 5.3 Popover component with custom HTML content, not the plain-text default
Manual trigger mode — the popover opens/closes only via explicit JS calls, so its own buttons stay clickable
Only one popover open at a time; opening a new one closes any other
Clicking outside the open popover or its trigger closes it, same as a native dropdown
Confirm and Cancel are real buttons wired to real handlers, not decorative text
No modal, no backdrop, no full-screen dim — the confirmation stays anchored to its trigger

About this UI Snippet

Bootstrap Popover Confirm Delete — HTML, CSS & JavaScript

Screenshot of the Bootstrap Popover Confirm Delete snippet rendered live

A confirmation modal is overkill for deleting one row from a list — it dims the whole page for a single yes/no decision. This snippet uses real Bootstrap 5.3's Popover component instead, configured with html: true and a custom content string containing two real buttons (Delete, Cancel), so the confirmation appears right next to the action that triggered it rather than taking over the screen.

The one non-obvious step: extending the allowList

Bootstrap's popover sanitizes any HTML content it's given by default, checked against an internal allowlist of permitted tags and attributes — and <button> is not on that default list. Passed as-is, both the Delete and Cancel buttons in the content string above would be silently stripped before the popover ever rendered, leaving an empty confirmation with nothing to click. The fix is allowList: { ...bootstrap.Popover.Default.allowList, button: ['type', 'class'] } — spreading Bootstrap's own default list and adding one explicit entry for the tag this content actually needs, rather than disabling sanitization outright (which would also drop the XSS protection sanitize:true exists for).

Each trigger gets its own bootstrap.Popover instance created with trigger: 'manual', meaning the popover only opens or closes when JavaScript explicitly calls .toggle()/.hide() — Bootstrap's default hover/click auto-triggering wouldn't leave room for the Delete/Cancel buttons inside the popover to be clicked before it closed. A page-level click listener also closes whichever popover is open if a visitor clicks anywhere outside it, and only one popover is ever open at a time.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Hand this snippet's HTML, CSS, and JS to an AI coding assistant like Claude and ask it to add a loading state on the confirm button while a real delete API call is in flight, or to add an Escape-key handler that closes the open popover. It's also a good exercise to ask the assistant to generalize this into a reusable confirmPopover(triggerEl, { message, onConfirm }) helper function usable on any element.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a Bootstrap 5.3 inline delete-confirmation popover, using the real Bootstrap CDN framework (bootstrap.min.css and bootstrap.bundle.min.js), not custom CSS made to resemble Bootstrap.

Requirements:
- A list of at least three items, each with a "Delete" button.
- Clicking a Delete button opens a real Bootstrap Popover (new bootstrap.Popover with html: true and trigger: "manual") positioned above the button, containing custom HTML content: a confirmation message naming that specific item, and two real buttons — a red "Delete" and a "Cancel".
- Clicking the popover's own Delete button must remove that item's row from the list and close the popover; clicking Cancel must close the popover without removing anything.
- Only one popover should ever be open at a time — opening a new one must close any other that's currently open.
- Clicking anywhere outside the open popover and its trigger button must also close it, without deleting anything.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Load the snippetClick the snippet in the sidebar Library tab. The preview loads a 3-item file list.
  2. 2
    Click "Delete" on any rowA real Bootstrap popover opens above the button with a confirm message and two buttons.
  3. 3
    Click "Cancel"The popover closes and the row is untouched.
  4. 4
    Click "Delete" again, then confirmClick the row's Delete button, then the popover's red "Delete" — the row is removed and the "Deleted" readout updates.
  5. 5
    Try opening a popover then clicking elsewhereOpen one, then click blank space on the page — it closes without deleting anything.

Real-world uses

Common Use Cases

Deleting rows from a list or table
An inline popover confirmation is lighter-weight than a modal for single-item deletions in a list, table, or file browser.
Learning manual-trigger Popovers
A concrete example of trigger: "manual" mode, needed anytime a popover's own content must remain interactive.
Any low-stakes destructive action
Reuse this pattern for "remove," "unfollow," or "archive" actions where a full modal would be excessive friction.
Admin panels and file managers
A natural fit alongside the Bootstrap Admin Dashboard snippet's data rows for quick, in-place row actions.

Got questions?

Frequently Asked Questions

Real Bootstrap 5.3 — it's the actual Popover component (new bootstrap.Popover(el, options)) with html: true and a custom content string, loaded from the genuine Bootstrap CDN.

Bootstrap's default click/hover triggers would close the popover as soon as the pointer moved to click one of its own Confirm/Cancel buttons. Manual mode means only explicit .toggle()/.hide() calls open or close it, so its interactive content stays usable.

Bootstrap sanitizes any HTML passed to a popover by default, checked against an internal allowlist of tags and attributes — and <button> isn't on that default list. Without extending it, both the Delete and Cancel buttons in the content string would be silently stripped before the popover ever renders, leaving an empty confirmation. Spreading bootstrap.Popover.Default.allowList and adding a button entry fixes this while keeping sanitization's XSS protection intact for everything else.

It removes the row from the DOM in this front-end demo. Wire the confirm handler's click listener to a real DELETE API call before removing the row for actual persistence.

No — clicking a new trigger explicitly hides any other currently-open popover first, so there's never more than one confirmation visible at a time.

Clicking its Cancel button, or clicking anywhere outside both the trigger and the open popover itself — a document-level click listener handles the outside-click case.