DEV Community

Ajay D
Ajay D

Posted on

Native HTML Series Part 3: Popover API

Native HTML Series Part 3: Tooltips and Menus with the Popover API

Welcome to Part 3 of our series on replacing third-party UI libraries with native HTML. We’ve already covered zero-JS accordions and native modals. Today, we are looking at the newest tool in the browser's arsenal: the Popover API.

Think about how often you build tooltips, user profile dropdowns, or custom toast notifications. Historically, getting these to float above your content without z-index bugs—while also remembering to close them when the user clicks somewhere else—required a dedicated JavaScript library or writing complex event listeners.

The new popover attribute solves all of this natively.

The Bare Bones

Unlike <dialog>, which is a specific HTML tag, popover is a global attribute. You can attach it to a <div>, an <article>, or any other element to instantly turn it into a floating popup.

Here is the entire HTML required to create a working popover menu, with absolutely zero JavaScript:

<button popovertarget="user-menu">Open User Menu</button>

<div id="user-menu" popover>
  <ul>
    <li><a href="#">Profile</a></li>
    <li><a href="#">Settings</a></li>
    <li><a href="#">Sign Out</a></li>
  </ul>
</div>

Enter fullscreen mode Exit fullscreen mode

That's it. By linking the button's popovertarget to the id of the div, the browser handles the click events completely behind the scenes.

The Magic: Built-In Light Dismiss

In Part 2, we had to write a JavaScript function to close our modal when the user clicked the background.

With the Popover API, this behavior (known as "light dismiss") is built-in by default. When a popover is open, doing any of the following will automatically close it:

  1. Clicking anywhere outside the popover.
  2. Pressing the Escape key.
  3. Opening another popover.

Furthermore, just like the <dialog> element, popovers are promoted to the browser's "Top Layer," guaranteeing they will always sit on top of your other content, regardless of the parent container's overflow: hidden or z-index rules.

The CSS Glow-Up

By default, an open popover is just centered in the middle of the screen. We can use CSS to style it as a sleek, floating menu and add transitions using the :popover-open pseudo-class.

/* Style the popover box */
[popover] {
  padding: 1rem;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);
  background: white;

  /* Basic positioning - reset defaults */
  margin: auto; 
  max-width: 250px;
}

/* Remove default list styling for our menu */
[popover] ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

[popover] li {
  padding: 0.5rem 0;
  border-bottom: 1px solid #f1f5f9;
}

[popover] li:last-child {
  border-bottom: none;
}

Enter fullscreen mode Exit fullscreen mode

Note: For true relative positioning (e.g., anchoring the popover exactly below the button), you would use the new CSS Anchor Positioning API, which pairs perfectly with popovers but is a topic for a future post!

Why This Matters

The Popover API is a massive win for developer experience. It standardizes one of the most common UI patterns on the web. It means less JavaScript sent to the client, fewer accessibility bugs, and a much cleaner DOM. If you are writing end-to-end tests with tools like Playwright, testing these interactions becomes a breeze because the browser's native state is completely predictable.

Interactive Demo:
(Click the button below to see the popover in action. Notice how clicking anywhere else on the screen instantly closes it—no JS required!)

Top comments (0)