Open UI logo

If it pops, it belongs in HTML and CSS! Lately, I had a lot of fun playing around with this upcoming feature. The first version is being developed and it's starting to look pretty good. It's time to handle our basic popovers without the explicit need of JavaScript.

I always wanted to learn about W3C communities and since the end of 2022, I started to get involved with Open UI. I contribute by creating demos, trying things out, listening closely to the meetings and following up the GitHub repo. It’s been a very interesting learning experience and I hope to do a bit more in the future with this awesome W3C community.

To spread the word a bit about the cool things this group is achieving, I thought I’d write this little article with a bit of information on the group itself and the basics of the Popover API. I’m planning to write more about this, so you might call this: “the first of a series”.

What is Open UI?

Open UI is a W3C community group in a quest to allow web developers to style and extend built-in web UI components and controls. Think about current UI elements that you can’t style such as the listbox of a <select> or a color picker, but it’s more than that. Your basic “web UI” where you normally would need JS such as tooltips, notes, panels and general pop-ups such as alerts.

Keep in mind that the mission is not to replace or update the current web UI, but rather to give us the tools to create our own design systems in a much more convenient way (can’t break the web, but sure as hell can enhance it).

To do this, the group works a lot around the parts, states and behaviour of the current UI and a large part of that is accessibility. They approach this by doing research around the large number of design systems out there and carefully mapping out what these systems have in common. On a personal note, I think that this will be the biggest strength, being able to style what couldn’t be styled before and getting the accessibility out of the box. If you’ve never heard of it and you love what you’re hearing, you can read the full charter.

You can start playing around with it

There is already a Popover API implementation in Chrome Canary. All you need to do is go to chrome://flags and enable the experimental web platform features. So keep in mind that this article is written with the current state in mind and is subjected to change. I will try to update this as much as possible.

What is a popover, pop-up, etc…

They are not built-in to the web and we usually use JavaScript to handle them. There are some common characteristics that the Open UI group thinks about. Usually they are on top of every other content, they can be “lightly dismissed” by clicking beside it or pressing the ESC key and usually there is only one “active” at the same time.

Because they are on top of every other element, it makes perfect sense that a popover should be added to the top-layer, which is technically outside of the document flow. This is beneficial as we won’t have to hurt our brains on managing our z-index in CSS (let’s admit, we’ve all been there…)

There is a lot of information on the Popover API on the website and I won’t be copying all of the things written there. Instead, it’s demo time!

Basic usage of the Popover API

We can define a Popover by using the popover attribute. By default, the popover will have the “auto” value but we can set it to “manual” as well. Here is the basic syntax:

<div id="some-popover" popover>
  Hi, I'm a popover!

The popover will automatically be hidden inside of the top-layer.

The two different values of popover:

  • popover=”auto” is the default and will create a popover that has a light dismiss. It can be closed by either clicking outside of it, or pressing the ESC key on the keyboard.
  • popover=”manual” will result in a popover that can’t be light dismissed. So a custom action should be provided if needed. If you want the user to perform a specific action within the popup and then close it, this is your value of choice.

One of the biggest strengths of this new API, is that we can choose our own elements and aria-roles for it. In contrast to the dialog element which always gets the dialog role. Yes, this comes with some responsibility, but this also means that we can use it for multiple cases with some careful planning by using the correct elements or roles such as dialog, tooltip, alert, etc…

If you want to read up about the differences between the Popover API and the <dialog> element. There is a great article on that by Hidde: Dialogs, modality and popovers seem similar. How are they different?

Showing, hiding and toggling the popover

What I personally love about this Popover API is that we don’t need any JavaScript to toggle our popovers. To open up our popover, we can simply add the following button to toggle it:

<button popovertarget="some-popover" popovertargetaction="toggle">Open the popover</button>
<div id="some-popover" popover>
  Hi, I'm a popover!

This button introduces two new attributes:

  • popovertarget will reference the id of the popover we wish to show, hide or toggle.
  • popovertargetaction provides the action that should occur, options are: “show”, “hide” or “toggle”.

The popovertargetaction is an optional attribute and the default is set to “toggle”.

These attributes are only supported on buttons (including: <button>, <input type=”button”>, etc.) as long as the button would not submit a form. In that case the form would be submitted and the popover would not be toggled.

If we would like to create a popover where we don’t want a light dismiss, we can easily create this by doing the the following:

<button popovertarget="some-popover" popovertargetaction="show">Open the popover</button>
<div id="some-popover" popover="manual" role="dialog">
  Hi, I'm a popover!
  <button popovertarget="some-popover" popovertargetaction="hide">Close the popover</button>

An important note on focus trapping

Popovers do not have focus trapping by default. The reason for that is because they are meant to be used in multiple conditions. Take for example an alert; You might not want to trap focus there but instead keep the focus on the element that triggered the alert. It is however possible to add the “autofocus” attribute on (or inside) the popover element which should help with your initial focus. But remember, this is only changing the next focus and isn’t the same as focus trapping itself.

Take note: If you’d like to use this for a modal you will need to implement your own focus trapping with JavaScript, and use additional ARIA attributes. Alternatively, one could simply use the <dialog> element with the .showModal() method.

Here is a default example of the Popover API on codepen (Remember, use Chrome Canary for now).

Animating our popovers

The initial demo used to animate before by only using transitions, but during the standardization process this was removed in favor of something else. There are a few open issues at the CSSWG which make a lot more sense for transitioning the popovers. Most of these are part of the css-transitions-2 spec and include:

You can still animate the entry of the popover by using CSS animations, but when it comes to transitions we will have to wait a bit. Here is an animated example 🙂:

How to anchor our top-layered popovers to other items in our DOM - The anchoring API

It’s difficult to track relative positioning because a popover is outside of the document flow. But there are use cases where we want to “anchor” our popup to another element, especially when you think about tooltips, alerts, etc… So how can we do this?

Luckily, there is another new kid on the block, which is the “Anchoring API”. It will allow us to tether elements to each other with CSS positioning. I’ll just go over this quickly, but if you want to read up on that, there is a great intro to the anchoring API by Jhey Tompkins on the Chrome blog.

For the final demo in this article, we just need the basics. For anchoring to work, we need to give our element an anchor-name:

.the-anchor {
  anchor-name: --myCoolAnchor;

Now if we want to hang our top-layered element to this anchor, we can use the anchor name and its position:

.my-toplayered-element {
  position: absolute;
  top: anchor(--myCoolAnchor top);
  left: anchor(--myCoolAnchor center);

Handling multiple popover positions for tooltips.

To handle multiple popovers such as tooltips, or in this case toggle tips, we can always add the name inside of a custom property.

My tooltip “toggle” will then get an inline style with that custom property and we will use this as an anchor name in CSS.

<button style="--anchor-name: --tooltip-1;" popovertarget="tooltip" popovertargetaction="toggle">click this!</button> 
    button {
      anchor-name: var(--anchor-name);

Our popover itself will then receive a custom property as well that we can anchor to the toggling element:

<span id="tooltip" style="--anchor: --tooltip-1;" role="note" popover>
  <span class="popover-inner">
    ✨Peek-a-boo✨<br />I'm a little popover
[popover] {
  position: absolute;
  top: anchor(var(--anchor) top);
  left: anchor(var(--anchor) center);
  max-width: 300px;
  transform-origin: center;
  transform: translate(-50%, -100%);

This way we can create a dynamic system for our “toggletips”, full demo and video:

What about hovers for tooltips?

For the moment it seems that hover and focus popups will be picked up in the future, but it’s coming! There are a lot more accessibility caveats to be discussed for those.

Final thoughts on popovers and Open UI

I think Open UI is one of the best things being worked on at the moment. It might partially be due to frustration of JavaScript libraries not being accessible, slowing my page down or not being customizable enough. I’ve worked with a lot of libraries and hacked a lot of them as well just to get the layout that was needed. This Popover API and things such as <selectmenu> will really make a big impact on the web. I’ve played a lot with <selectmenu> as well, but that’s also something for a later stage (and probably another article in the future).

I really enjoyed following the meetings as well, it’s so nice that this is an open group. I’m mostly contributing by listening, learning, spreading the word, creating demos and maybe giving a little opinion or two. This community is really getting attention from the right people. It’s great to follow along with this story and I’m sure many awesome things will be created in the future by the work these people are doing right now. Especially combined with the Anchoring API, the future for styleable UI has never been brighter.

Everyone can contribute! So if you’re interested, it’s time to get involved with Open UI.

I also want to add a little word of thanks to @jh3yy, @hdv and @gregwhitworth for taking the time to help me out and reviewing this article. 🙏

 in  html , css , ux , accessibility