> Markdown version of [/magazine/555-understanding-the-popover-api](https://www.wearedevelopers.com/magazine/555-understanding-the-popover-api). Every page supports `.md` or `Accept: text/markdown`. Links point to the HTML versions so they work for humans too. Agent guide: [/agents.md](https://www.wearedevelopers.com/agents.md). --- # Understanding the Popover API **By:** [Daniel Cranney](https://www.wearedevelopers.com/@daniel-cranney) **Published:** March 4, 2025 The Popover API is a powerful addition to web development, enabling developers to create lightweight, dismissible UI elements with ease. This native feature simplifies popover creation without requiring JavaScript event listeners or managing focus manually. However, when working with frameworks like Next.js, developers often rely on React state management and hooks like useEffect to handle similar functionality. In this article, we will explore the Popover API, compare it with traditional approaches, and discuss how it contrasts with React-based implementations. ## Key Features of the Popover API The Popover API introduces several useful capabilities: **Promotion to the top layer:** Popovers automatically appear above other content without requiring CSS z-index adjustments. **Light-dismiss functionality:** Clicking outside a popover closes it and returns focus to the triggering element. **Built-in focus management:** When a popover opens, focus is automatically moved to an interactive element inside it. **Keyboard accessibility:** Pressing the Esc key or toggling the popover button twice will close it. **Declarative binding:** The popover attribute enables a semantic connection between the trigger and the popover element. ## Implementing a Basic Popover Creating a popover is straightforward using HTML attributes. Here’s a simple example: <button popovertarget="my-popover">Open Popover</button> <div id="my-popover" popover> <p>I am a popover. Press <kbd>Esc</kbd> or click outside to close.</p> </div> In this example, the button has a `popovertarget` attribute pointing to the `id` of the popover. The `div` containing the popover has the `popover` attribute. The popover follows light-dismiss behavior by default. ## Different Types of Popovers By default, the popover behaves as `popover="auto"`, which allows automatic dismissal. However, you can explicitly define popover behavior: ### Manual Popovers Manual popovers require explicit closing actions: <button popovertarget="manual-popover">Open Popover</button> <div id="manual-popover" popover="manual"> <p>This popover won’t close automatically.</p> <button popovertarget="manual-popover" popovertargetaction="hide">Close</button> </div> Here, the popover remains open until the user clicks the close button, preventing automatic dismissal. ## Popover vs. Modal Dialogs At first glance, popovers and modal dialogs appear similar, but they serve different purposes: | Feature | Popover | Modal Dialog | | --- | --- | --- | | **Open Method** | `popovertarget` attribute | `dialog.showModal()` | | **Close Method** | `popovertargetaction="hide"` | `dialog.close()` | | **Light-Dismiss** | Yes | No | | **Blocks Interaction** | No | Yes (makes background inert) | | **Styling** | `:popover-open` | `[open]` attribute | While popovers work well for tooltips, dropdowns, and inline help messages, dialogs are more suited for blocking interactions like confirmation prompts. ## The React Approach When working with React, developers often use a mix of useStateand useEffect (or something similar) to handle popovers. Since HTML popovers are not yet widely supported across all browsers, it has become fairly standard-practice for React developers to create controlled popovers in this way. It usually goes a little something like this: import { useState } from 'react'; export default function PopoverComponent() { const [isOpen, setIsOpen] = useState(false); return ( <div> <button onClick={() => setIsOpen(!isOpen)}>Open Popover</button> {isOpen && ( <div className="popover"> <p>I am a popover. Click outside to close.</p> <button onClick={() => setIsOpen(false)}>Close</button> </div> )} </div> ); } In principal, there’s no issue with this approach, but aside from the fact it doesn’t include the light-dismiss behaviour, it took a lot more code to achieve the same basic result. Now if we were to add a light-dismiss behaviour, we were tag our modal wrapper with a useRef of `popoverRef`, and check if the user has clicked outside of the modal element in a useEffect, and set the `isOpen` to `false` if they have clicked outside of it. useEffect(() => { function handleClickOutside(event) { if (popoverRef.current && !popoverRef.current.contains(event.target)) { setIsOpen(false); } } if (isOpen) { document.addEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isOpen]); Developers themselves can’t be blamed for doing this, because it made sense as a workaround for a the lack of support for the popover API. So, now that it’s here, it’s worth trying out, right? ## Which Approach Should You Use? We recommend using the Popover API if: - You want a declarative approach with built-in light-dismiss behavior. - You aim for minimal JavaScript and improved performance. - You want to support the web platform Use React state solutions: - You need more control over popover behavior, animations and styling. - You are working in a React/Next.js environment where component reactivity is key, and these approaches are more common-place (so more readable and recognisable for other team members). - You need to support older browsers that lack Popover API support. ## Conclusion The Popover API simplifies UI development by introducing a declarative way to create accessible, dismissible elements. While it reduces JavaScript complexity, React developers are accustomed to managing UI state explicitly using hooks. Depending on your project’s needs, you may opt for the native Popover API or stick with controlled React components. Either way, understanding both approaches will help you build more maintainable and accessible user interfaces. ## Related Articles - [The HTML Elements That You’re Probably Over-Engineering](https://www.wearedevelopers.com/magazine/646-the-html-elements-that-you-re-probably-over-engineering) - [16 Best Free React UI Libraries in 2025](https://www.wearedevelopers.com/magazine/148-16-best-free-react-ui-libraries-in-2025) - [3 JavaScript-Free Techniques for Accordions, Dialogs, and Table of Contents](https://www.wearedevelopers.com/magazine/684-3-javascript-free-techniques-for-accordions-dialogs-and-table-of-contents) - [View Transition API: Adding Single-Page Transitions With Just HTML, CSS and JS](https://www.wearedevelopers.com/magazine/632-view-transition-api-adding-single-page-transitions-with-just-html-css-and-js) ## Related Videos - [What’s New and What’s Next in Web UI](https://www.wearedevelopers.com/videos/956-what-s-new-and-what-s-next-in-web-ui) - [Building Interactive Async UI with React 19 and Ariakit](https://www.wearedevelopers.com/videos/1589-building-interactive-async-ui-with-react-19-and-ariakit) - [Dos and don'ts with react hooks. An opinionated approach](https://www.wearedevelopers.com/videos/957-dos-and-don-ts-with-react-hooks-an-opinionated-approach) - [New Browser APIs, End of React Create App, Smuggling Data in Emoji and more with Rowdy Rabouw](https://www.wearedevelopers.com/videos/1299-new-browser-apis-end-of-react-create-app-smuggling-data-in-emoji-and-more-with-rowdy-rabouw) ## Related Jobs - [React Engineer for Next.js UI - Hybrid, Impactful FinTech](https://www.wearedevelopers.com/jobs/ext/1444505-react-engineer-for-next-js-ui-hybrid-impactful-fintech) at **Bitpanda** - [React Engineer For Next.Js Ui - Hybrid, Impactful Fintech](https://www.wearedevelopers.com/jobs/ext/1934580-react-engineer-for-next-js-ui-hybrid-impactful-fintech) at **Bitpanda** - [Senior Software Engineer, React (Investing & Trading)](https://www.wearedevelopers.com/jobs/ext/1937625-senior-software-engineer-react-investing-trading) at **Bitpanda** - [Senior Software Engineer, React (Websites & Martech)](https://www.wearedevelopers.com/jobs/ext/1605272-senior-software-engineer-react-websites-martech) at **Bitpanda** - [Software Engineer, React & Angular (Broker Web Platform](https://www.wearedevelopers.com/jobs/ext/1558399-software-engineer-react-angular-broker-web-platform) at **Bitpanda** - [Software Engineer](https://www.wearedevelopers.com/jobs/ext/1304673-software-engineer) at **Bitpanda**