Intent to Ship: The Popover API

1,006 views
Skip to first unread message

Mason Freed

unread,
Mar 17, 2023, 3:00:09 PM3/17/23
to blink-dev

Contact emails

mas...@chromium.org

Explainer

https://open-ui.org/components/popup.research.explainer

Specification

https://html.spec.whatwg.org/multipage/popover.html

Summary

An API that can be used to build transient user interface (UI) elements that are displayed on top of all other web app UI. These include user-interactive elements like action menus, form element suggestions, content pickers, and teaching UI. This API uses a new `popover` content attribute to enable any element to be displayed in the top layer. This is similar to the <dialog> element, but has several important differences, including light-dismiss behavior, popover interaction management, animation and event support, and the lack of a "modal" mode.



Blink component

Blink>HTML>Popover

TAG review

https://github.com/w3ctag/design-reviews/issues/743

TAG review status

Issues addressed

Risks



Interoperability and Compatibility



Gecko: Positive (https://github.com/mozilla/standards-positions/issues/698)

WebKit: Positive (https://github.com/WebKit/standards-positions/issues/74)

Web developers: Positive Generally positive feedback from OT participants and OpenUI developer discussion.

Other signals:

WebView application risks

Does this intent deprecate or change behavior of existing APIs, such that it has potentially high risk for Android WebView-based applications?



Debuggability

A feature has been added to devtools which shows all of the elements that are currently in the top layer, plus annotations of those elements in the Elements tree. Elements that use the popover API will be shown with this feature.



Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?

No

Is this feature fully tested by web-platform-tests?

No

Flag name

#enable-experimental-web-platform-features

Requires code in //chrome?

False

Tracking bug

https://crbug.com/1307772

Measurement

https://chromestatus.com/metrics/feature/timeline/popularity/4191
https://chromestatus.com/metrics/feature/timeline/popularity/4465

Estimated milestones

OriginTrial desktop last114
OriginTrial desktop first106
DevTrial on desktop104
OriginTrial Android last114
OriginTrial Android first106
DevTrial on Android104
OriginTrial webView last114
OriginTrial webView first106


Anticipated spec changes

Open questions about a feature may be a source of future web compat or interop issues. Please list open issues (e.g. links to known github issues in the project for the feature specification) whose resolution may introduce web compat/interop risk (e.g., changing to naming or structure of the API in a non-backward-compatible way).



Link to entry on the Chrome Platform Status

https://chromestatus.com/feature/5463833265045504

Links to previous Intent discussions

Intent to prototype: https://groups.google.com/a/chromium.org/g/blink-dev/c/9y-Thg9UCxY/m/_4gShWjQAAAJ
Intent to Experiment: https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CAM%3DNeDjJOC2%2B5aHfAoN8wOx8T0gtm%3D-o6eNK5XD6Ps5iRet6zA%40mail.gmail.com
Intent to Extend Experiment: https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CAM%3DNeDgMYePRFVsPLWyzKUYgkygR4C7iT88--h0zXGBKeckXeQ%40mail.gmail.com
Intent to Extend Experiment: https://groups.google.com/a/chromium.org/g/blink-dev/c/r3IwTXB8MG8/m/d4SjSV-GAgAJ


This intent message was generated by Chrome Platform Status.

Philip Jägenstedt

unread,
Mar 17, 2023, 4:19:22 PM3/17/23
to Mason Freed, blink-dev
Hi Mason,

This will be great, looking forward to seeing it ship!

Two questions inline and bonus API-owner-hat-off question:

Do you have a use counter for this feature which you'll use to track adoption? Do you have a ballpark guess about what the usage will be like a year from now?

(There's an idea in Web Compass to track adoption of ~all features and check in when it's way above/below expectations. We're trying to figure out the minimum questions to ask, and how to not make it annoying.)
Which platforms will it be supported on?

Is this feature fully tested by web-platform-tests?

No

How complete is https://wpt.fyi/results/html/semantics/popovers? Will the remaining Chrome failures there be fixed before shipping?

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CAM%3DNeDibTKMw-JK97b4UE1Z6TdaODxUArcM8YsLDGwAV29mOYw%40mail.gmail.com.

Mason Freed

unread,
Mar 17, 2023, 4:41:21 PM3/17/23
to Philip Jägenstedt, blink-dev
On Fri, Mar 17, 2023 at 1:19 PM Philip Jägenstedt <foo...@chromium.org> wrote:
This will be great, looking forward to seeing it ship!

Thanks!
 
Two questions inline and bonus API-owner-hat-off question:

Do you have a use counter for this feature which you'll use to track adoption? Do you have a ballpark guess about what the usage will be like a year from now?

Yes, the main use counter for all usage is this one. There are also value-specific counters here and here.

As far as a ballpark guess in usage, I really don't know. Obviously I'm hopeful that it's high, especially given that both WebKit and Gecko are working on an implementation. But hard to put a number on it. As I've been working on this feature, as I browse the web, *many* things feel like popovers, which all could hopefully benefit from this API.
 
(There's an idea in Web Compass to track adoption of ~all features and check in when it's way above/below expectations. We're trying to figure out the minimum questions to ask, and how to not make it annoying.)

On Fri, Mar 17, 2023 at 8:00 PM Mason Freed <mas...@chromium.org> wrote:


Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?

No

Which platforms will it be supported on?

Weird, not sure why that says "No". It used to say "Yes", which is the correct answer. I'll go update chromestatus accordingly.
 

Is this feature fully tested by web-platform-tests?

No

How complete is https://wpt.fyi/results/html/semantics/popovers? Will the remaining Chrome failures there be fixed before shipping?

It should be very complete. I think this feature is well tested.

Thanks for pointing out those failures. Several of those (related to focus) should show up green as soon as some recent changes land on WPT. One (the light-dismiss test) is odd, and I'll take a look at it. All of the popover tests pass on Chromium's infra.

Thanks,
Mason

Alex Russell

unread,
Mar 17, 2023, 9:23:46 PM3/17/23
to Mason Freed, Philip Jägenstedt, blink-dev

Jake Archibald

unread,
Mar 18, 2023, 4:39:20 AM3/18/23
to Mason Freed, blink-dev
https://github.com/whatwg/html/issues/9045 - I don't think show/hide should throw if the popover is already shown/hidden. However, dialog has this same issue, and going from throw to not-throw is generally a backwards compatible change.

https://github.com/whatwg/html/issues/9046 - I don't think the timing of the toggle event is right, but dialog also has a similar issue.

https://github.com/whatwg/html/issues/9043 - the toggle method is inconsistent with other toggle methods, but this should be a backwards compatible change.

I don't think these should block shipping, but shipping mustn't block these issues being fixed.

--

Mason Freed

unread,
Mar 18, 2023, 10:53:33 AM3/18/23
to Jake Archibald, blink-dev
On Sat, Mar 18, 2023 at 1:39 AM Jake Archibald <jakear...@google.com> wrote:
https://github.com/whatwg/html/issues/9045 - I don't think show/hide should throw if the popover is already shown/hidden. However, dialog has this same issue, and going from throw to not-throw is generally a backwards compatible change.

https://github.com/whatwg/html/issues/9046 - I don't think the timing of the toggle event is right, but dialog also has a similar issue.

https://github.com/whatwg/html/issues/9043 - the toggle method is inconsistent with other toggle methods, but this should be a backwards compatible change.

Right - I’m participating in these conversations, so I’m guessing you are just pointing them out here for the benefit of the api owners?

I don't think these should block shipping, but shipping mustn't block these issues being fixed.

Agreed. None of these seem like breaking changes, and are easy to implement. Plus, the shipping target is 114, which still has a month before it branches.

Thanks,
Mason

Jake Archibald

unread,
Mar 18, 2023, 12:34:03 PM3/18/23
to Mason Freed, blink-dev
On Sat, Mar 18, 2023 at 2:53 PM Mason Freed <mas...@chromium.org> wrote:
On Sat, Mar 18, 2023 at 1:39 AM Jake Archibald <jakear...@google.com> wrote:
https://github.com/whatwg/html/issues/9045 - I don't think show/hide should throw if the popover is already shown/hidden. However, dialog has this same issue, and going from throw to not-throw is generally a backwards compatible change.

https://github.com/whatwg/html/issues/9046 - I don't think the timing of the toggle event is right, but dialog also has a similar issue.

https://github.com/whatwg/html/issues/9043 - the toggle method is inconsistent with other toggle methods, but this should be a backwards compatible change.

Right - I’m participating in these conversations, so I’m guessing you are just pointing them out here for the benefit of the api owners?

Correct! Just pointing out that changes may happen soon after shipping, but that it's probably ok.

Mason Freed

unread,
Mar 18, 2023, 12:45:05 PM3/18/23
to Jake Archibald, blink-dev
On Sat, Mar 18, 2023 at 9:33 AM Jake Archibald <jakear...@google.com> wrote:
On Sat, Mar 18, 2023 at 2:53 PM Mason Freed <mas...@chromium.org> wrote:

Right - I’m participating in these conversations, so I’m guessing you are just pointing them out here for the benefit of the api owners?

Correct! Just pointing out that changes may happen soon after shipping, but that it's probably ok.

Awesome, thanks. Hopefully the changes (at least for these three) can happen *before* shipping. We’ve been incorporating many tweaks like this recently, as WebKit has been doing their own implementation and finding corner cases.

Noam Rosenthal

unread,
Mar 20, 2023, 4:19:06 AM3/20/23
to blink-dev, Mason Freed
Voicing some concern about this API that I've raised before, and perhaps I'm reading this wrong and it was addressed.
Think of CMS-style sites that embed user-generated HTML, like Wikis (I worked on popups for wikipedia).
This HTML is usually sanitized to remove potentially malicious tags (<script>, <object>) and also script-invoking events (on* etc).
One of the things those content system have to do is make sure that the embedded content is clearly separated from the platform UI.
That is usually done with z-index & overflow. No matter how you play around with your embedded content, if it is embedded inside a stacking/overflow context, it can't go on top of the platform UI.

By allowing showing/hiding top-layer elements without JS, we break this contract and existing HTML sanitation-based systems. Wiki and some other existing CMSs can resolve this by special-casing popover attributes in their sanitizers, but I wonder if it would break existing content systems that don't have that privilege, don't know about it, or are not actively developing their HTML sanitizer.

Note that this concern is only about the capability to open a popup without JS. 

Philip Jägenstedt

unread,
Mar 20, 2023, 6:26:19 AM3/20/23
to Noam Rosenthal, blink-dev, Mason Freed
Hi Noam,

Do you know if these sanitizers generally work as allowlists or blocklists? In other words, will the new popover attribute be allowed through current versions of those sanitizers?

Best regards,
Philip

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Jake Archibald

unread,
Mar 20, 2023, 6:38:01 AM3/20/23
to Philip Jägenstedt, Noam Rosenthal, blink-dev, Mason Freed
DOMPurify seems to block the popover attribute, and I don't see any code for handling it specifically, so I assume it's not on an allowlist.

Noam Rosenthal

unread,
Mar 20, 2023, 6:59:19 AM3/20/23
to Philip Jägenstedt, blink-dev, Mason Freed
https://github.com/apostrophecms/sanitize-html for example is allow-list by default but can be configurable to work as a block-list.

This is hypothetically a problem for any new HTML attribute, however with this particular one we break a very old CSS contract (stacking/overflow contexts are only esacapable by JS).

Mason Freed

unread,
Mar 20, 2023, 2:13:25 PM3/20/23
to Noam Rosenthal, blink-dev
On Mon, Mar 20, 2023 at 1:19 AM Noam Rosenthal <nrose...@chromium.org> wrote:
Voicing some concern about this API that I've raised before, and perhaps I'm reading this wrong and it was addressed.
Think of CMS-style sites that embed user-generated HTML, like Wikis (I worked on popups for wikipedia).
This HTML is usually sanitized to remove potentially malicious tags (<script>, <object>) and also script-invoking events (on* etc).
One of the things those content system have to do is make sure that the embedded content is clearly separated from the platform UI.
That is usually done with z-index & overflow. No matter how you play around with your embedded content, if it is embedded inside a stacking/overflow context, it can't go on top of the platform UI.

By allowing showing/hiding top-layer elements without JS, we break this contract and existing HTML sanitation-based systems. Wiki and some other existing CMSs can resolve this by special-casing popover attributes in their sanitizers, but I wonder if it would break existing content systems that don't have that privilege, don't know about it, or are not actively developing their HTML sanitizer.

Note that this concern is only about the capability to open a popup without JS. 

Thanks for raising this issue. You and I discussed this several months ago. I think my view is the same as before: using `z-index` and `overflow` as some kind of security boundary is a bit fragile, and not what those features were designed to do. There *is* a platform API that *does* have this behavior as its official contract: `<iframe>`. As you mentioned, you already need to use a sanitizer to preserve z-index boundary, since `dialog.showModal` or `anyElement.requestFullscreen()` or even `document.body.appendChild()` breaks out of it. And given that sanitizers are a) required for this use case anyway, b) always require upkeep to ensure they're filtering the right things, and c) should be using allowlists or they're already broken, it seems like that's the path forward for this type of CMS use case, right? Probably the attribute that should be filtered is `popovertarget`, to avoid the declarative invocation behavior.

Thanks,
Mason

Noam Rosenthal

unread,
Mar 21, 2023, 3:01:43 AM3/21/23
to Mason Freed, blink-dev
On Mon, Mar 20, 2023 at 8:13 PM Mason Freed <mas...@chromium.org> wrote:
On Mon, Mar 20, 2023 at 1:19 AM Noam Rosenthal <nrose...@chromium.org> wrote:
Voicing some concern about this API that I've raised before, and perhaps I'm reading this wrong and it was addressed.
Think of CMS-style sites that embed user-generated HTML, like Wikis (I worked on popups for wikipedia).
This HTML is usually sanitized to remove potentially malicious tags (<script>, <object>) and also script-invoking events (on* etc).
One of the things those content system have to do is make sure that the embedded content is clearly separated from the platform UI.
That is usually done with z-index & overflow. No matter how you play around with your embedded content, if it is embedded inside a stacking/overflow context, it can't go on top of the platform UI.

By allowing showing/hiding top-layer elements without JS, we break this contract and existing HTML sanitation-based systems. Wiki and some other existing CMSs can resolve this by special-casing popover attributes in their sanitizers, but I wonder if it would break existing content systems that don't have that privilege, don't know about it, or are not actively developing their HTML sanitizer.

Note that this concern is only about the capability to open a popup without JS. 

Thanks for raising this issue. You and I discussed this several months ago. I think my view is the same as before: using `z-index` and `overflow` as some kind of security boundary is a bit fragile, and not what those features were designed to do. There *is* a platform API that *does* have this behavior as its official contract: `<iframe>`.
<iframes> come with additional constraints. e.g. some of this embedded HTML can position itself in the page (as long as it doesn't go "on top" of other things), and you can't apply global CSS into iframes. There's a reason people use embedded HTML rather than iframes for certain use-cases, and stacking/overflow contexts gives some confidence that the embedded HTML doesn't try to go on top of the embedding UI.
 
As you mentioned, you already need to use a sanitizer to preserve z-index boundary, since `dialog.showModal` or `anyElement.requestFullscreen()` or even `document.body.appendChild()` breaks out of it. And given that sanitizers are a) required for this use case anyway, b) always require upkeep to ensure they're filtering the right things, and c) should be using allowlists or they're already broken, it seems like that's the path forward for this type of CMS use case, right? Probably the attribute that should be filtered is `popovertarget`, to avoid the declarative invocation behavior.

Sanitizers are just one way to set a boundary for embedded HTML. The other one is preventing JS using CSP. 
Looking at the major sanitizers in use today (e.g. Github markdown, Wiki HTML sanitizer) they use allowlists so this would not present a problem for them.
I don't think this should be a blocker for this feature (which I'm really excited about!) but I raised it to a wider audience because I think we should stay aware of this issue. We're relaxing a very old constraint here (albeit for good reasons).

 

Mike Taylor

unread,
Mar 22, 2023, 11:52:52 AM3/22/23
to Noam Rosenthal, Mason Freed, blink-dev

LGTM2

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Philip Jägenstedt

unread,
Mar 22, 2023, 11:57:22 AM3/22/23
to Mike Taylor, Noam Rosenthal, Mason Freed, blink-dev

Mason Freed

unread,
Mar 22, 2023, 8:07:14 PM3/22/23
to Philip Jägenstedt, Mike Taylor, Noam Rosenthal, blink-dev


On Wed, Mar 22, 2023 at 8:57 AM Philip Jägenstedt <foo...@chromium.org> wrote:
LGTM3

Thanks for the LGTMs!
 
On 3/21/23 3:01 AM, Noam Rosenthal wrote:
Thanks for raising this issue. You and I discussed this several months ago. I think my view is the same as before: using `z-index` and `overflow` as some kind of security boundary is a bit fragile, and not what those features were designed to do. There *is* a platform API that *does* have this behavior as its official contract: `<iframe>`.
<iframes> come with additional constraints. e.g. some of this embedded HTML can position itself in the page (as long as it doesn't go "on top" of other things), and you can't apply global CSS into iframes. There's a reason people use embedded HTML rather than iframes for certain use-cases, and stacking/overflow contexts gives some confidence that the embedded HTML doesn't try to go on top of the embedding UI. 
That's true, <iframes> aren't free, and they do come with additional constraints. I just meant they are the one platform primitive that actually explicitly guarantees the contract that contained content can't escape.
 
As you mentioned, you already need to use a sanitizer to preserve z-index boundary, since `dialog.showModal` or `anyElement.requestFullscreen()` or even `document.body.appendChild()` breaks out of it. And given that sanitizers are a) required for this use case anyway, b) always require upkeep to ensure they're filtering the right things, and c) should be using allowlists or they're already broken, it seems like that's the path forward for this type of CMS use case, right? Probably the attribute that should be filtered is `popovertarget`, to avoid the declarative invocation behavior.

Sanitizers are just one way to set a boundary for embedded HTML. The other one is preventing JS using CSP. 
Looking at the major sanitizers in use today (e.g. Github markdown, Wiki HTML sanitizer) they use allowlists so this would not present a problem for them.
I don't think this should be a blocker for this feature (which I'm really excited about!) but I raised it to a wider audience because I think we should stay aware of this issue. We're relaxing a very old constraint here (albeit for good reasons).
That's a good point. I don't feel like an opt-in for this behavior is warranted, given that this isn't really the contract provided by z-index and top-layer. But I can see the need for an opt-out, similar to CSP for JS. Would you mind opening a WHATWG/html issue about this, and we can discuss in more detail there?
 
Thanks,
Mason
Reply all
Reply to author
Forward
0 new messages