The Popover API is a native browser feature — enabled by adding a popover attribute to any element — that handles show/hide, focus trapping, light-dismiss, and top-layer stacking without JavaScript. For WordPress themes and plugins it eliminates jQuery-based modal and dropdown code.
Problem: WordPress admin interfaces use custom JavaScript-powered tooltips and dropdowns that require event listeners, positioning logic, and focus-trap management — duplicating browser functionality that is now available natively.
Solution: Use the HTML Popover API — add popover attribute to the tooltip or dropdown element and popovertarget="id" to the trigger button. The browser handles show/hide toggling, light-dismiss on outside click, and top-layer stacking automatically. Style with :popover-open and animate entry/exit with @starting-style.
The examples below build an accessible popover tooltip, animate it with CSS, create a non-modal confirmation dialog, and show how to hook WordPress admin popovers into the Popover API.
/* Popover base styles — popover elements are hidden by default */
[popover] {
/* Reset browser UA sheet defaults for popovers */
margin: 0;
padding: 1rem 1.25rem;
border: 1px solid #ddd;
border-radius: 6px;
background: #fff;
box-shadow: 0 4px 20px rgb(0 0 0 / .15);
max-width: 320px;
/* Entry animation using @starting-style */
opacity: 1;
translate: 0 0;
transition: opacity 0.2s, translate 0.2s,
overlay 0.2s allow-discrete,
display 0.2s allow-discrete;
}
@starting-style {
[popover]:popover-open {
opacity: 0;
translate: 0 -8px;
}
}
/* Exit animation */
[popover]:not(:popover-open) {
opacity: 0;
translate: 0 -8px;
}
/* The :popover-open pseudo-class styles the open state */
[popover]:popover-open {
display: block;
}
HTML markup and JavaScript for WordPress admin popovers:
// Minimal HTML (no JavaScript needed for basic open/close):
//
// Popover content here
// Clicking the button toggles the popover. Clicking outside dismisses it (light-dismiss).
// popover="auto" (default) — light-dismiss, only one open at a time
// popover="manual" — must be closed explicitly via JavaScript
// JavaScript API for programmatic control:
const popover = document.getElementById( 'my-popover' );
// Show / hide / toggle
popover.showPopover();
popover.hidePopover();
popover.togglePopover();
// Listen for open/close events
popover.addEventListener( 'toggle', ( e ) => {
if ( e.newState === 'open' ) {
console.log( 'Popover opened' );
loadPopoverContent( popover ); // lazy-load content on first open
}
} );
// WordPress admin: turn the existing colour picker into a popover
document.querySelectorAll( '.wp-color-result' ).forEach( btn => {
const picker = btn.nextElementSibling;
if ( ! picker ) return;
// Convert existing class-based show/hide to Popover API
picker.setAttribute( 'popover', 'auto' );
btn.setAttribute( 'popovertarget', picker.id || ( picker.id = 'color-' + Math.random().toString(36).slice(2) ) );
// Remove old jQuery toggle handler to avoid double-firing
btn.removeEventListener( 'click', btn._legacyHandler );
} );
NOTE: The Popover API is supported in all modern browsers since 2023 (Chrome 114, Firefox 125, Safari 17). It automatically manages focus, closes on Escape, and places the element in the top layer — solving the z-index stacking context problems that plague traditional modal implementations in WordPress admin.