skip navigation

The popover API

The new popover API consists of HTML, CSS and JavaScript to create and manage popovers.

But first what is a popover?

A popover consists of two HTML elements. The first is an HTML element that is hidden and revealed after clicking a button. The second is that button to click. Note that only a button element or an input type="button" element may be used for this.

This is the popover which comes with some default browser styles. The only difference it has from a regular div is a popover attribute and an ID which allows it to be targetted by the button.

The HTML

A popover can be created with just some HTML. Specifically two new attributes, popover and popovertarget.

To get started first add the popover attribute to the HTML element you wish to use:

<div popover id="my-popover">
    <!-- some text etc.. -->
</div>

Next the button element just requires the popovertarget attribute to tell the browser which element to reveal:

<button popovertarget="my-popover">Toggle popover</div>

There are several things to take note of with this default setup.

  1. The popover button has a toggle action. It reveals then hides the popover. This default behaviour can be changed by adding a popovertargetaction attribute and setting it to show or hide. The default, when not set, is toggle.
  2. The popover can be closed with the button or by clicking anywhere away from the popover element or by pressing the Esc key. This is because the default behaviour for the popover attribute is auto. You can set this to manual which means it cannot be closed that way any more: <div popover="manual" id="my-popover">.

This popover has it's popover attribute set to manual: popover="manual".
This prevents it from closing using by clicking away from the element or using the Esc key.

The popover buttons have a popovertargetaction set to : show and hide respectively.
This overrides the default toggle behaviour when this attribute is not set.

Nested popovers

The button for a popover can be inside another popover.

The popover has another popover button nested inside.
The popover buttons have a popovertargetaction set to : show and hide respectively.
This overrides the default toggle behaviour when this attribute is not set. I've set the background to green to make it more visible.

This can be useful for menus for example.

Styling

Like any HTML element the browser applies default styles to popover elements. Here is what Chromium browsers do:

[popover] {
    position: fixed;
    width: fit-content;
    height: fit-content;
    color: canvastext;
    background-color: canvas;
    inset: 0px;
    margin: auto;
    border-width: initial;
    border-style: solid;
    border-color: initial;
    border-image: initial;
    padding: 0.25em;
    overflow: auto;
}

You may want to change some or all of these. You can apply any valid CSS to the popover element.

Additionally there are some extra styles to be aware of. Like the HTML dialog element an open popover element can use the ::backdrop pseudo element which can be styled in different ways.

This popover uses the ::backdrop pseudo element with the backdrop-filter: blur(5px) and a transparent background-color. Notice how you can still open and close the other modals on the page.

There’s also a CSS pseudo-class :popover-open which lets you style and popover element only when it’s open.

Styling animations

When a popover element is hidden it’s display is set to none. When made visible it’s set to fixed. To animate between these two values you cannot use CSS transitions. Instead there is a new CSS way, `@starting

However by setting the popover to display: block surprisingly it still remains hidden. You can then add CSS transformations in this initial state and in the :popover-open state and get the popover to be animated on

This popover is set to display: block overriding the browser style display: none. It's then hidden from view using scale: 0 and scale: 1 with the :popover-open pseudo-class.

This popover is not yet done.
blah blah blah.. display: block overriding the browser style display: none. It's then hidden from view using scale: 0 and scale: 1 with the :popover-open pseudo-class.

Popover or dialog?

There’s a lot of similarity between popovers and the HTML <dialog> element. So much so you might wonder what the difference is.

A popover supports light-dismiss1. A modal dialog does not. A modal dialog makes the rest of the page inert. A popover does not.

Chrome dev blog

And..

A dialog is often displayed when users need to be made aware of something or when they need to choose. Do you want to continue, yes or no? If you want to open a new file, what shall we do with your current file, save or delete? How do you want to crop this image, where is the hot spot?

Canonically, dialogs are a lot like window.confirm(), window.alert() and window.prompt(), which the HTML specification lists under ‘simple dialogs’. But unlike these browser built-in dialogs, custom dialogs offer more flexibility—you get to put whichever content and styling you want inside of them.

Hidde blog post

The Hidde blog post has a lot more, in depth analysis of the differences.


  1. A light dismiss simply means the element can be closed by clicking anywhere outside of it. This is the default behaviour of a popover though that can be changed with the popovertargetaction attribute on the button set to show or hide↩︎