Closed mfreed7 closed 2 years ago
At the last OpenUI meeting, I took an action item to put together a comparison of the various "popup-like" use cases.
I was able to pull much of the needed information from the OpenUI popup research page, which was nice. I pulled that together with a few other sources (e.g. WAI-ARIA), and constructed this table:
https://docs.google.com/spreadsheets/d/1v4RXKrvp-txG477GNH42gFSzX_HkRYJk-eap6OgAorU/edit?usp=sharing
It lists all of the closely-related UI patterns that I've heard in our discussions, and compares them along various dimensions. I also took a stab at assigning HTML elements to each UI pattern, to try to start the conversation about which elements belong to the "generic" <popup>
-type element, and which deserve their own separate element.
To focus the conversation in one place, I did not enable comments on the spreadsheet above - please add your comments here in this thread. I will attempt to keep the doc up to date with the comments here. Again, this was intended to be a first cut at some research on the behaviors, and I'm sure I missed many important things. Please help me find them.
some quick comments on some of the aria role assumptions here.
re: navigation menu. what exactly is the use case here? I question if this would actually be a role=navigation, and not instead a list. I'd rather expect a button that invoked this sort of content to already be within a navigation landmark... or not, if it's not actually necessary to expose such items as a nav. A landmark that is hidden by default is not particularly useful.
re: teaching ui - still don't understand why this is being classified as a popup, other than it needing some of the proposed functionality that is being associated with popup. seems it should just be a dialog element?
re: <alert>
, toast/popup notification... role=alert
is not always the correct choice there, and especially not true if it's going to receive focus (in response to the 'typically not focused").
The Open UI Community Group just discussed [Popup] What types of elements should be excluded from <popupdialog> usage?
.
It's a bit disappointing to see the discussion seems to be going in circles, continuing to revisit old ideas like using popup as a non-semantic wrapper element around more-specific semantic elements. People even continue to bring up the analogy with picture, which I tried to be clear about is not a good analogy---picture is a hack around the fact that art direction for images needs to interact with the preload scanner in a declarative and backward-compatible way, and not a precedent to be used for future features that don't have the same constraints.
I was initially really heartened to see Mason's breakdown in the spreadsheet, and interested in getting into some of the detailed discussions. Indeed, I thought the breakdown was really helpful in how it revealed the dramatically different focus behaviors, invocation behaviors, and keyboard behaviors. (The spreadsheet even understates that case, marking many things "green" which in reality behave differently and probably shouldn't be grouped together.) That made it clear to me that our previously-agreed-upon path forward of splitting this up into multiple non-overlapping elements was going to work out well, and bring utility for developers.
But if people are still coming back to trying to make a generic popup element that serves all these use cases, even three weeks after this thread started (and three months after the original concern was raised), I'm getting a bit discouraged.
It's possible I'm just not interpreting the meeting transcript correctly, and if so, I apologize! But I was hoping it would concentrate on concrete questions like "are teaching UIs a good fit for a new element or is dialog good" or "are dismiss semantics for selectmenu actually light-dismiss on all platforms or do we need to vary them per-platform" or "should we split pickers out from generic popups due to their different focus and keyboard behavior". Those would be really worthwhile questions for this group, I think!
Per @domenic's comment, I'm reading over the minutes and I want to clarify some of my points, as maybe I was unclear.
My reference to the picture element was, as my previous time bringing it up, the only way I could see popup being an element - a container that represented nothing but its allowed descendant elements, and like the picture element, not allow for aria-* attributes to be specified on it. I recall @domenic and @melanierichards not being sold on the idea (which I briefly alluded to in the IRC chat), but at the time I didn't interpret that as a flat out "no". So apologies for my misunderstanding / bringing up that line of discussion again.
However, if that comparison is not an acceptable pathway forward, then I'm at a loss for how this could be an element itself, and not an attribute (or css?) which could be applied to specific elements to indicate they can have popup behavior, e.g., listbox, datepicker, menu, - all of which would be welcome static elements that don't always need to be popped up. Or an attribute on a dialog to, for instance, provide a semantic cue / means to provide an a11y api mapping to indicate this non-modal dialog will dismiss if focus leaves it. As then AT could expose that as a hint of the element's behavior.
Deviating a bit, but concerning the idea of teaching ui and popups that largely contain static content, i.e., "more info" popups... There is a note
role in ARIA that is being fleshed out a bit more in its definition, and it seems like it could possibly fit these use cases if dialog
were not deemed appropriate. A note being an element that contains additional information about another element/section of content, and unlike a tooltip, could have nested interactive elements, such as links. Like elements such as listbox
, it would make sense to be either static/in line with other content, or popup.
Thanks Scott; something about your comment really made this click for me and brought out an implicit assumption underlying much of what I've been saying.
However, if that comparison is not an acceptable pathway forward, then I'm at a loss for how this could be an element itself, and not an attribute (or css?) which could be applied to specific elements to indicate they can have popup behavior, e.g., listbox, datepicker, menu
I think this comes down to an interesting question I don't know the answer to: should a popping-up listbox be thought of as a listbox in a dialog, or as a listbox that happens to be presented in a certain way?
The most important angle from which to consider this question is from AT and AT users' expectations. That angle also connects it to the concrete technical question of whether the accessibility tree should say dialog(non-modal) > listbox
or just listbox
. But it's also an interesting question from the point of view of abstract semantics, and developer teachability and mental models.
If a listbox-in-a-dialog is the right model, then <popupdialog>
(role=dialog) with nested <listbox>
(role=listbox) makes sense. But if listbox-presented-as-popup is the right model, then <listbox popup>
makes sense, and we need to proscribe people from using <popupdialog>
for listboxes.
Note that for listbox we need to introduce the listbox role into the tree one way or another. For other cases Mason lists, namely teaching UI, date picker, generic picker, or "generic" popup (not really sure what these are...), the question can be approached from a different angle, since those things don't have a separate role and so should be nested inside a <dialog popup>
or <popupdialog>
that is responsible for setting the role.
Stated another way, I'm comfortable evolving <popupdialog>... hand-crafted code for a date picker ...</popupdialog>
into <popupdialog><datepicker></datepicker></popupdialog>
in the future, if we ever get around to a <datepicker>
element, because to my knowledge <datepicker>
does not have a dedicated role; it's really just a series of many controls each of which have their own role, and that series may or may not live inside a dialog. But evolving <popupdialog>... hand-crafted code for a listbox ...</popupdialog>
into <popupdialog><listbox></listbox></popupdialog>
only seems tenable if the correct model is indeed listbox-in-a-dialog, and not listbox-presented-as-popup.
My implicit assumption was that listbox-presented-as-popup was correct, which leads to the general direction of this GitHub issue: <popupdialog>
could be created and used for specific cases, and proscribed for other cases. If that implicit assumption is wrong, and listbox-in-a-dialog is correct, then we could contemplate speccing and shipping <popupdialog>
(or <dialog popup>
) earlier than <listbox>
, and not proscribing its use as a container for listbox. Probably some people will forget to use role=listbox
when implementing their listbox-in-a-dialog, but that's no worse than today where they forget role=listbox
when implementing their non-popping-up listboxes. The important thing is that we haven't introduced a new semantic-less element; our new element has dialog semantics.
Maybe that's been the big disconnect between me and others this whole time.
Thanks Scott; something about your comment really made this click for me and brought out an implicit assumption underlying much of what I've been saying.
However, if that comparison is not an acceptable pathway forward, then I'm at a loss for how this could be an element itself, and not an attribute (or css?) which could be applied to specific elements to indicate they can have popup behavior, e.g., listbox, datepicker, menu
I think this comes down to an interesting question I don't know the answer to: should a popping-up listbox be thought of as a listbox in a dialog, or as a listbox that happens to be presented in a certain way?
Yes. +1 to this entire post. I think I had similar thoughts, but they didn't crystalize until I read this post. Essentially, from an AT point of view, there is a difference between a listbox in the page and a pop-up listbox. One is in page, and can be navigated to/from sequentially. The pop-up listbox requires more immediate attention, since it's "in a separate window" and is meant "to prompt the user to enter" information (from role=dialog). That distinction (in-page vs dialog) is already denoted by the "dialog" role on the wrapping element. The fact that the thing is a listbox is denoted by the element with role="listbox", and that should be the same whether it sits in the page or in a popup/dialog. In other words, it makes total sense to have a wrapping element that says "my content needs more immediate attention" and a contained element that says "I'm a listbox" or "I'm an action menu" or whatever.
I also very much appreciate the comments on the evolution paths. Going from <popupdialog><div id=hand_crafted_listbox role="listbox"></popupdialog>
to <popupdialog><listbox /></popupdialog>
should be natural and easy for developers to understand and follow.
so using listbox
as the example: for standard custom listboxes
that are popups now, there is no dialog wrapper. there is an element (generally a combobox) that has an aria-haspopup=listbox
and when navigating to that element, it informs the user that a popup can be invoked. so then when the user invokes said popup, they will be moved to and start interacting with the elements of the listbox. Depending on the AT there may be a listbox announcement, or you might just hear that you are interacting with options directly. Point being that there is no dialog
semantics in this instance.
However, there are instances of more complex popups where say an element has aria-haspopup=dialog
. This dialog then could contain a series of individual controls. a textbox and a listbox, for instance. In that situation a user would be presented with the information that they are going to invoke a dialog of some sort. focus moving to the dialog then allows them to interact with the individual controls of this more complex listbox + other component. Being that the user was informed they were going to enter a 'popup', there is then an implicit understanding that (if they are allowed to) leave the wrapping dialog, then it is likely going to dismiss.
so, per the expectations for the different types of elements, a standard popup listbox
would not be expected to be contained in an element that had dialog semantics / mappings. It'd be introducing unnecessary information. A more complex series of controls / information that has popped up... that would make more sense to expose as a dialog
as that's an indicator that "something is going to show up here, but it doesn't neatly fit into menu
, listbox
, tree
or grid
roles" - as are the current aria-haspopup
values.
hopefully that helps clarify expectations on the a11y mapping end as well? And also are there additional roles we might need to define (e.g., formally define datepicker
and standardize exactly what sub-elements are expected in such a container?), or at least need to indicate could be roles that might be expected to 'popup'.
Let's call this a):
so using
listbox
as the example: for standard customlistboxes
that are popups now, there is no dialog wrapper. there is an element (generally a combobox) that has anaria-haspopup=listbox
and when navigating to that element, it informs the user that a popup can be invoked. so then when the user invokes said popup, they will be moved to and start interacting with the elements of the listbox. Depending on the AT there may be a listbox announcement, or you might just hear that you are interacting with options directly. Point being that there is nodialog
semantics in this instance.
and this b):
However, there are instances of more complex popups where say an element has
aria-haspopup=dialog
. This dialog then could contain a series of individual controls. a textbox and a listbox, for instance. In that situation a user would be presented with the information that they are going to invoke a dialog of some sort. focus moving to the dialog then allows them to interact with the individual controls of this more complex listbox + other component. Being that the user was informed they were going to enter a 'popup', there is then an implicit understanding that (if they are allowed to) leave the wrapping dialog, then it is likely going to dismiss.
Please help me understand this. (I'm honestly asking.) From an AT user's point of view, what is the material difference between a) navigating to an element that "informs the user that a popup can be invoked" and upon invocation, they are "moved to and start interacting with the elements of the listbox", and b) navigating to an element that presents "the information that they are going to invoke a dialog of some sort" and upon invocation lets them "interact with the individual controls of this" component?
Those seem, naively to me at least, to present the same information to the user. In both cases, they understand that something will "pop up", and typically tells them how to get it to "pop up". When invoked, they get further announcements about where they can go from there, based on what popped up. Even the use of "pop up" doesn't make sense to me for unsighted users. Conceptually, the "dialog" role is described as "an application dialog or window that separates content or UI from the rest of the web application or page." - that's about separation between the main page/flow and something "outside" the page/flow, and likely something needing more immediate attention. It seems mostly unrelated to what it contains. The "listbox" role is about content, and is described as "lists from which a user may select one or more items". So to me, <dialog><listbox></listbox></dialog>
makes complete semantic sense: it describes something "separate from the main page" that contains "a list of options". On the contrary, <listbox></listbox>
without the <dialog>
describes an in-page list of options that I can directly interact with.
I tried out a sample page containing a <select>
and a <button aria-haspopup=dialog>
connected to a <dialog>
element, with Chrome on a Mac, using Voiceover. Both of them show up in the Accessibility Tree as a "Combobox" (not a "listbox", even for the <select>
), and both are announced to the user nearly identically. The <select>
is announced as a "menu popup collapsed button", while the <button>
is a "dialog popup button". Both of them then announce this identically: "to display a list of options, press Ctrl Option Space". From a user's point of view, are these materially different? I'm guessing most users get the most value from that last sentence.
i think at this point you may have gotten some of the answers you were looking for outside of this thread, @mfreed7? But to semi-quickly answer, so as to not just leave this thread / your question hanging, I will respond to hopefully clarify A vs B.
A: an element indicates it will invoke a popup - in this example, a combobox where the default expectations is a listbox. Upon encountering the combobox the user knows that it will invoke a listbox (generally), and being a listbox popup it has an expected interaction pattern. There is no need for, nor a desire, to expose a containing element role for this listbox
. It's functionality is implicit by the means in which it was invoked, and people know how to interact with it per the expectations that come along with the listbox
role (which does presently have variants to how it is announced depending on AT and platform).
B: an element indicates it will invoke a popup dialog. In this case the AT user is forewarned that they will encounter a dialog (but to be fair, that doesn't have to be the case (indicating exactly what type, from a limited set, of element will be popped up) and there is discussion in the ARIA WG about this topic). Invoking and then entering this dialog informs a user that there may be additional content and controls to interact with - because generally the "dialog" role that is the containing element is announced, and this serves as the clue for the user to explore the contents of it. Using a dialog to contain a single control and only that control, e.g., a listbox
would be unexpected as there's no reason to need a dialog to contain solely a listbox. The dialog would just add extra noise and uncertainty.
To summarize, and per Domenic's description, A's expectation would be "listbox-presented-as-popup". We do not want a dialog (or any other container "role" to be announced if a listbox is a popup)
For example B: <popup> more than a single type of control or maybe even some static content</popup>
would be the expectation. Here, we might need a role to be exposed for the containing element... maybe not in some cases... it kinda depends on what the expected functionality of the content of the popup is, and what the expectations are for containing focus within this popup would be. This is why I've been so unsure about this scenario... but per other conversations that have gone on, I'm hopeful we can have a good discussion on this next time we talk about popup
.
I can add more comments on this if necessary, but i hope that at least helps clarify a bit your asks about what I was trying to indicate with A vs B.
On the call, it was mentioned it would be helpful to have a list of use cases where a default dialog
or group
role would not be desired. These are the ones @scottaohara and I could come up with in a brief brainstorm:
menu
ARIA role)Here are some use cases where a non-modal dialog would work:
Thanks @smhigley and @scottaohara! This matches my expectation, and going further:
tooltips (desired role: none or tooltip) toasts -- specifically because of the on-open focus behavior of a dialog
I would say these are not <popup>s
at all due to behavioral differences, as well as the specific and narrow content model expectations for tooltip. There will be a danger of devs reaching for popup to make a tooltip or toast, so we should think about how to address that need on the platform.
The Open UI Community Group just discussed Elements excluded from popupdialog usage
.
Thanks for the good discussion on this issue today.
Refining the lists provided above, during the last few meeting conversations, and in the OP, it is sounding like:
Not for use with <popup>
:
<popup>
)<popup>
)<dialog>
)These are more specific UI patterns for which there should be either a separate element (e.g. <listbox>
), or for which role=Xyz
should be used to correctly set the role:
role=listbox
)role=list
)role=menu
)role=tree
)role=grid
)These are more specific UI patterns for which role=dialog
seems correct:
These are more specific UI patterns for which role=dialog
might not apply, and for which role=none
or role=group
might be better:
*I could use some clarification on these. @smhigley, would it be possible to point to specific examples on the web for these? I know what an in-page tree or grid looks like, but I'm trying to better understand the use case for a popup that is just a tree or grid with no other controls. Also, for the single-form-control popups, it would be good to see a "good" example of this as well, to see what the right role should be. Don't these typically come with a few other buttons like at least "Mute"? And in that case, aren't they dialogs?
I am starting to get worried that we're not moving toward a solution. If we're unable to come to a consensus on a way forward for this "popup-like" functionality, developers will be stuck using <div>
s appended as the last child of <body>
with z-index:99999
and a lot of Javascript to get these behaviors. That does not sound terrifically semantic or accessible to me. I'm really hoping we can come to some sort of compromise on this issue, to improve this situation for everyone!
or for which role=Xyz should be used to correctly set the role:
Recall that we cannot introduce a new HTML element which is intended to be used with the role ARIA attribute, per discussions here and in previous threads about how doing so violates the first rule of ARIA. So these elements would need to be in the proscribed list for the popupdialog element.
I agree that it's not clear where this is going, since I saw such pushback in the minutes against our previous agreement to use the dialog role, and only use popupdialog for cases where that is appropriate. It might be time to step back and start considering more outside-the-box solutions, such as CSS or JS primitives. The element approach seems overconstrained between some people's desire for a multi-purpose element and the requirements of HTML language design and accessibility which make such generic elements a bad idea. CSS and JS APIs don't have such constraints and so for those who want a multi-purpose tool (which seems to include you, Mason) they are probably the right path forward.
can't link to a real world example, being behind a login, but here's the apg example of grid popup - no wrapping dialog. similarly with a treeview. we have them at microsoft for some comboboxes that have nested levels of available options to them.
an example of a volume slider that can 'popup' when invoked by a button. a cable company i contracted for had one of these that visually looked more complex, but was merely just a single range slider that was heavily styled and light dismissed when focus left. no need for a dialog as that'd just add unnecessary verbosity to a simple control.
Other examples of something like this, which would likely more benefit from popup functionality, would be similar slider controls related to zooming in/out/rotating web-based 3d rendering UI. This would be particularly helpful in context of zoomed in interfaces where standard css positioning might be fine for a larger screen use case, but in the context of a UI zooming up to 400% to meet reflow criteria, UI can be collapsed to ensure that as much workspace is available as possible.
in other words, the ability to make something 'popup' via CSS/JS, rather than requiring an element would be far more conducive to responsive UI, as specifically requiring an element container that exposed an unnecessary role would be unfortunate in either situation.
It might be time to step back and start considering more outside-the-box solutions, such as CSS or JS primitives.
I wanted to drop in here and second this. I would like to use the <selectmenu>
as a concrete example of why I feel this way. If we look at the extensible model that Open UI is built on then we result with the following initial anatomy:
<selectmenu>
<slot name="button-container">
<button></button>
</slot>
<slot name="listbox-container">
<listbox>
<slot>
<opt-group>
<option>
</opt-group>
</slot>
</listbox>
</slot>
</selectmenu>
In order to add popup functionality with only an element we have to wrap the listbox
with popup
. Like so:
<selectmenu>
<slot name="button-container">
<button></button>
</slot>
<slot name="listbox-container">
<popup>
<listbox>
<slot>
<opt-group>
<option>
</opt-group>
</slot>
</listbox>
</popup>
</slot>
</selectmenu>
So now if a developer wants to adjust the listbox to be inline we'll have to replace the markup via a slot when technically they don't have any desire to actually change content model but the rendering. Now I understand that popup
comes with additional behaviors as well. But the above is not a good DX, in my opinion. As such I'd recommend that we have them as primitives AND a general element that leverages those primitives. I'm leaning towards CSS as content attributes would result in the same issue described above unless we provide a way for declarative attribute reflection/modification for known children in a shadow DOM but this would complicate slotting etc and be a mess.
So then the UA CSS would look like this:
listbox, popup {
display: popup
}
This would enable an author to adjust listbox
to be inline via adjusting the display
value and they wouldn't loose any other controller functionality of a listbox but would remove the behaviors that are required for the generic popup usecases.
I think this aligns with the focusgroup
approach outlined by @travisleithead here, and one can then imagine focustrap, dismiss, type primitives. I don't want to boil the ocean here however and solely align on the correct model that we can continue to add to as developer need warrants the investment in unlocking more primitives. This aligns also with @LeaVerou feedback in the tag review.
I'm interested in your thoughts @dandclark since you're actively working on the selectmenu
and of course @mfreed7 and @melanierichards
Since it sounds like there’s a relatively strong response that this feature should be turned into either an HTML attribute or a CSS property, I have two questions:
<div showaspopup>
nor <div style=“display:popup”>
would have any accessibility implications. Is that correct?Retracting my comment here, as the more I think about this, I don't think my comment about being restrictive about particular elements makes sense. I'd support either providing popup functionality through attributes or CSS/JS.
Would there potentially be a11y implications to doing it this way? Sure. But no more so than there are presently a11y implications to using current HTML global attributes or CSS/JS in ways that aren't beneficial for accessibility. There are likely some safe fallbacks that could be mapped for generic elements to make them less likely to be problematic.
But providing these features via attributes/css would likely allow for more flexibility for authors than if restricted to a single element (which as I've mentioned before, would not always expose the expected semantics desired, depending on the content/component(s) it contained). Authors could even apply such attribute/css/js logic to current z-index hack implementations, rather than completely refactor to use an element that would still require polyfills for older browsers.
Not speaking for WHATWG here, but from my perspective from my other accessibility work / ARIA WG member, not all semantic HTML elements have strong accessibility semantics, nor do their semantic definition have to relate to a specific ARIA role. I'm going to pause on going any further on this topic for now though.
Ahoy 👋
This issue is labelled for discussion in the next teleconference. @mfreed7, as an editor of the proposal and the creator of this issue, would you be available and interested in discussing this in the teleconference for additional feedback?
If so, would this week or next week would best for you? Or was this issue already discussed? I’m unsure.
I’m unsure of its status, also, because I have read thru #455, and it seems like there’s an alternative approach that may or may not negate this. Again, I’m unsure.
I think it's safe to close this issue, as it relates to the "old" <popup>
element proposal.
See this comment for more context.
The
<popupdialog>
element (name TBD) is meant for "general purpose" transient non-modal dialogs, to be used only when there aren't more-specific element types. We need to enumerate those more-specific types, so that this recommendation makes sense.So the question is: what other elements are similar to popups behaviorally, but semantically different, and made for more specific purposes? These would constitute the list of other types of elements for which developers should not use
<popupdialog>
.This is a brainstorming issue, so I'll start with some candidates for this list, with (rough) links to some definitions for each:
<listbox>
- link<actionmenu>
- link<tooltip>
- link<toast>
- link<navmenu>
- link?What other ideas do folks have?