popover

HTML Popover API — Live Demos

5 examples · zero libraries

Hover Tooltip with CSS Anchor Positioning

The button has anchor-name: --tip-btn. The popover has position-anchor: --tip-btn; position-area: top. Zero Popper.js. Zero JavaScript.

CSS anchor positioning ✓ Zero JS
--:--:--Click the button to see the tooltip

The three lines that replace Popper.js

<!-- Trigger: name the anchor --> <button style="anchor-name: --tip-btn" popovertarget="tooltipDemo">Hover me</button> <!-- Popover: reference the anchor --> <div id="tooltipDemo" popover="manual" role="tooltip" style="position-anchor: --tip-btn; position-area: top; margin-bottom: 8px;"> Content here </div>

Dropdown Action Menu

A fully native dropdown. popover="auto" light-dismisses on outside click. Anchor positioning places it below-right of the button. Escape closes it.

popover="auto" ✓ Light-dismiss ✓ Escape closes
--:--:--Click Actions to open the dropdown

aria-expanded synced via toggle event

const btn = document.getElementById('dropBtn'); const menu = document.getElementById('dropMenu'); menu.addEventListener('toggle', (e) => { btn.setAttribute('aria-expanded', e.newState === 'open'); });

Toast Notification Stack

Each toast is popover="manual" — multiple can coexist. They slide in from the right and auto-dismiss after 3s. Click ✕ to dismiss early.

popover="manual"
--:--:--Click a button to spawn a toast notification

Why manual? — auto would kill the stack

popover="auto" closes all other auto popovers when a new one opens — so you'd only ever see one toast. popover="manual" lets them coexist independently.

function addToast(message, type) { const toast = document.createElement('div'); toast.setAttribute('popover', 'manual'); // ← key! toast.className = `toast ${type}`; container.appendChild(toast); toast.showPopover(); setTimeout(() => toast.hidePopover(), 3000); }

Command Palette — ⌘K

A popover centered in the viewport (no anchor needed). Opens on ⌘K / Ctrl+K, filters commands as you type, and runs commands on click or Enter.

⌘K popover="auto" ✓ Keyboard nav
--:--:--Click or press ⌘K / Ctrl+K to open

Center it without anchor positioning

/* Command palette: centered, not anchored to any button */ #cmdPalette { inset: 15vh auto auto 50%; transform: translateX(-50%); width: min(520px, 92vw); /* No position-anchor needed — fixed in viewport */ } /* Open via JavaScript, not popovertarget */ document.addEventListener('keydown', (e) => { if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); palette.showPopover(); } });

auto vs manual — side by side

Try them both. Notice how auto closes on outside click and Escape. Notice how opening a second auto popover closes the first. manual stays put until you explicitly close it.

popover="auto"

Light-dismiss, Escape to close, only one open at a time.

  • Click outside closes it
  • Escape key closes it
  • Multiple open at once
  • Closes others when opened

popover="manual"

Stays open until you explicitly close it. Multiple can coexist.

  • Click outside closes it
  • Escape key closes it
  • Multiple open at once
  • Closes others when opened
--:--:--Open each type and observe the behavior differences
auto popover open!
Click anywhere outside this box to close it. Press Escape. Open another auto popover — this one will close.
manual popover open!
Click outside — nothing happens. Press Escape — nothing. Click Close to dismiss.
Read the tutorial