Popover and Dialog in JS

Popover and Dialog from JavaScript

Interactive Elements declares popovers and dialogs in markup; script opens them when logic decides. showPopover(), hidePopover() and togglePopover() accept { source } (Chrome 137 1 , Firefox 144 555 , Safari 26 10 ), which ties the popover to its button for accessibility and anchoring. A <dialog> has show(), showModal(), close(value) and requestClose(value), which fires a cancelable cancel event first.

Opening a popover from script and logging its toggle eventsHTMLLive
<style>body { font: 15px system-ui; } #log { position: absolute; left: 240px; top: 0; }
  [popover] { margin: 0; inset: auto; position-area: bottom span-right; }</style>
<button id="menuButton">Account ▾</button> <pre id="log"></pre>
<div id="menu" popover>Signed in as <b>lip</b><br><button>Sign out</button></div>
<script>
  const say = (text) => (log.textContent += text + '\n');
  menu.onbeforetoggle = (e) => say(`beforetoggle → ${e.newState}`);
  menu.ontoggle = (e) => say(`toggle ${e.oldState} → ${e.newState}`);
  menuButton.onclick = () => menu.togglePopover({ source: menuButton });
  say(`togglePopover() returned ${menu.togglePopover({ source: menuButton })}`);
</script>
Browser output of Listing 9.49
Browser output of 49

beforetoggle fires synchronously (cancel it to refuse opening) and toggle afterward. Never set dialog.open = true: it skips the top layer, focus handling and ::backdrop.