Ryan Trimble
many lights blurred out

The Popover API is exciting, sort of

Front End Development

Photo Credit: Alexander Grey

At work, there is a particular component in our design system that I have made obvious I dislike immensely, yet I have not been able to figure out a solid replacement. We call it the “Info Box” and it’s essentially just a tooltip-style element that can contain more text and actions.

I’m not fond of it for several reasons, but mainly I dislike it because of the number of times we run into issues using it due z-index stacking.

While researching a few ways to make this component better, I have come across the new Popover API that has certainly piqued my interest.

The long and short of the Popover API is essentially it can turn any element into a top-layer popover. This means elements can live outside DOM structure, and the z-index stack, potentially helping with issues such as what we are facing with the Info Box.

A very important note: This is an experimental API and should not be used in production. The Popover API is currently only available in Chrome Canary but is planned to be available in standard Chrome starting with version 114+.

The Good

The Popover API is being developed as a native web API proposed by the Open UI group. The proposal had several great goals in mind for how popovers should function.

Accessible by default

Accessibility is an important consideration for any new features being added as native web APIs. The proposal for the popover API ensures a few things so popovers are accessible by default.

Popover elements are still semantically relevant to the DOM, however, they are rendered in a layer on top of all other content. Elements in the top layer still retain all semantics, user input, and focus.

Only one popover can be active at a time. Any elements added to the top layer will cause existing top-layer elements to be removed. This will prevent confusion or annoying interface behaviors that could be caused by popovers stacking on top of each other.

Also, popovers include built-in “light dismissal” functionality, which means that users can close a popover with the Esc key or click outside the popover as a default action. No need to write JavaScript to handle these actions.

Ease of use

To create a popover, simply add the popover attribute to an element within the HTML.

<div id="my-popover" popover>
  <p>This is a popover!</p>
</div>

The default value for the popover attribute is auto which enables the standard behaviors such as the light dismissal. If you are using JavaScript to control the popovers, the value of manual can be set to remove these standard behaviors.

Elements with the popover attribute are hidden with display: none until opened. Active popovers are position: fixed and centered in the viewport, with a barebones styling of white background and black border.

There are a few ways to activate popovers, but as part of the proposal, popovers can be opened without needing any extra JavaScript using popovertargetaction and popovertarget attributes.

Target actions include toggle to open and close, show to open, and hide to close popovers.

Targets point to the id of the popover that the selected action should happen to, for example:

<button 
  popovertargetaction="toggle" 
  popovertarget="my-popover">
  Open Toast
</button>

<div id="my-popover" popover>
  <p>This is a popover!</p>
</div>

This button will open and close the popover element with the id of my-popover.

Popovers can be styled like any other element with CSS. Popovers can be targeted for styling using the popover attribute:

[popover] {
  background: white;
  border: none;
  box-shadow: 0px 30px 80px rgba(0, 0, 0, 0.07);
  inline-size: min(100% - 1rem, 60ch);
}

Similar to the <dialog> element, backdrops can be styled using the ::backdrop pseudo-element.

[popover]::backdrop {
  background: rgba(0, 0, 0, 0.5);
}

Video showing the Popover API in action.

There are also JavaScript events and methods to work with popovers available as well.

The two methods are showPopover() and hidePopover() which can be used to show and hide popovers respectively. Similarly, onpopovershow and onpopoverhide are the two new events that can be used to trigger further functionality when popovers are utilized.

The Bad

Browser Support

The most obvious issue with the Popover API is the lack of browser support.

This reminds me of the View Transitions API, which is a Chrome-only API that I’m not sure will make it into other browsers (I certainly hope so!). Unlike the View Transitions API though, Popovers are not necessarily something that can easily be used as a progressive enhancement.

As it is still definitely experimental and was proposed by Open UI, I’m hoping Popovers can gain some traction with other browsers.

Alternatives

The most similar alternative to Popovers is the <dialog> element, but there are some key differences:

  • As far as I’m aware, the <dialog> element can only be opened and closed within JavaScript.
  • <dialog> does not have the same automatic light dismissals that Popovers do, another consideration that would need to be handled by JavaScript.
  • I’m also not sure I would consider every element in the top layer to be a dialog, so semantically sometimes it may make sense to use different elements.

Wrap up

It’s difficult to see solutions to problems you are facing just out of reach like this, but I am still very excited to see how the Popover API evolves — hopefully being adopted by more browsers.

There are so many new features being proposed, developed, and added to the web which will reshape the way we develop websites and applications. I’m always excited to learn more about new and potentially helpful features.

Let's work together!