Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the semantic role for <popup>? #410

Closed
mfreed7 opened this issue Oct 14, 2021 · 43 comments
Closed

What is the semantic role for <popup>? #410

mfreed7 opened this issue Oct 14, 2021 · 43 comments
Labels
popover The Popover API

Comments

@mfreed7
Copy link
Collaborator

mfreed7 commented Oct 14, 2021

This is a question raised by @domenic on the TAG review for the <popup>, here. Copying the relevant part from that comment:

We need to figure out what the similar semantic space, and corresponding role, is for <popup>. The explainer example seems to give several types of controls: menus, form element suggestions, content pickers, and teaching UI. What is the ARIA role for each of these? Perhaps each should have a separate element, not <popup>, which implements the appropriate semantics (and behaviors?? I can't imagine a teaching UI needs the exact same behaviors as a menu). Or perhaps some of those are better suited for <dialog> instead of <popup>.

Should we be proposing several "flavors" of popup instead as separate elements, e.g. <tooltip>, <listbox>, etc.?

@chrisdholt
Copy link
Collaborator

I think the difficult thing we'll get into when proposing different flavors is that only some of them are consistently directly related to "popup". So elements like <dialog> and <tooltip> would both benefit from popup and have semantic meaning, but not every <listbox> is a <popup>. You could compose the select's listbox using popup, but a listbox element could also just render as a block level element in my application and not need any of that popup code. My understanding of <popup> has been that by default it is primarily functional and behavioral to enable it being used across a variety of scenarios with different semantics. While I think popup can enable those scenarios functionally, I'm not sure that requiring it to have semantic meaning by default is the best course of action. Totally up for discussion and a good thing to officially resolve, but I think if we add semantics to popup by default we're may end up needing to add additional requirements that could make it harder to reuse across a broader spectrum of elements.

@mfreed7
Copy link
Collaborator Author

mfreed7 commented Oct 14, 2021

I think the difficult thing we'll get into when proposing different flavors is that only some of them are consistently directly related to "popup". So elements like <dialog> and <tooltip> would both benefit from popup and have semantic meaning, but not every <listbox> is a <popup>. You could compose the select's listbox using popup, but a listbox element could also just render as a block level element in my application and not need any of that popup code. My understanding of <popup> has been that by default it is primarily functional and behavioral to enable it being used across a variety of scenarios with different semantics. While I think popup can enable those scenarios functionally, I'm not sure that requiring it to have semantic meaning by default is the best course of action. Totally up for discussion and a good thing to officially resolve, but I think if we add semantics to popup by default we're may end up needing to add additional requirements that could make it harder to reuse across a broader spectrum of elements.

Thanks for the comment. This was my take also - we're adding a functional component called <popup> that can be used to build several different kinds of UI. Kind of like <dialog> really. As such, the element itself has less specific semantic meaning. I do think that the idea has always been to keep going with new elements, e.g. <tooltip>, and those might use a <popup> for functionality. Or <selectmenu>'s listbox, as you mentioned. But those will be the elements/uses that have more direct semantic meaning. And <popup> can represent the more generic concept of a "thing that pops up", which I guess is role=dialog with aria-modal=false.

@mfreed7
Copy link
Collaborator Author

mfreed7 commented Oct 14, 2021

By the way, this issue relates directly to #329.

@domenic
Copy link
Contributor

domenic commented Oct 14, 2021

Role=dialog with aria-modal=false is the dialog element, so if that's the desired semantic this proposal should be morphed into an update or extension of the dialog element.

I disagree strongly with the idea that dialog is a "functional component", or that such a concept is even something the HTML language contains. HTML elements provide specific semantics; if you're using them to express functionality divorced from semantics, then HTML is not the right language to implement the API in.

@chrisdholt
Copy link
Collaborator

Role=dialog with aria-modal=false is the dialog element, so if that's the desired semantic this proposal should be morphed into an update or extension of the dialog element.

To be clear here, the desired semantic is none for popup. The intent of the element is functional; it could be used to build semantic elements such as the positioning, focus delegation, etc of dialog, but we are looking at usage well beyond dialog and with quite varying semantics (listbox of select menu).

@domenic
Copy link
Contributor

domenic commented Oct 14, 2021

Yeah, as I said in my edit, "the desired semantic is functional" is a contradiction in terms. It sounds like maybe this API is best done through JavaScript, not HTML---e.g. some JS function that lets you give an arbitrary element light dismiss behavior, or put it in the top layer. Then the semantics can be provided by HTML, and the functionality is done through JavaScript, in congruence with web platform design principles.

@chrisdholt
Copy link
Collaborator

Yeah, as I said in my edit, "the desired semantic is functional" is a contradiction in terms. It sounds like maybe this API is best done through JavaScript, not HTML---e.g. some JS function that lets you give an arbitrary element light dismiss behavior, or put it in the top layer. Then the semantics can be provided by HTML, and the functionality is done through JavaScript, in congruence with web platform design principles.

Just to be clear, I denoted “none” rather than functional as the desired semantics. I get your point, but it is an important difference IMO and I’d be curious how “none” is a contradiction as far as implicit role, etc. Is the bar for any new element an applied semantic that maps to ARIA? I’ll let others chime in here, but if the ask is to revisit this as a JavaScript API then it would be great to see that presented as an alternative. Much of this seems to exist in the platform already at some level (putting elements in the top layer), but isn’t exposed to authors. The intent of the element is to allow authors to compose UI without necessarily requiring JS. It seems reasonable to have that as an ask, but I’m certainly open to hearing why that’s not a feasible approach.

@chrisdholt
Copy link
Collaborator

@domenic as a quick follow-up, I just was reading up more through your responses in the linked issue. You mention:

No, this isn't correct. The dialog element can only be used for dialogs. Tooltips or toasts should be done using

s or similar. (Or perhaps a new element, if someone were bold enough to propose one... I seem to recall something of that sort for toasts.) If you use but then override its exposure to accessibility tech using role=something else, the element is being misused.

I think, perhaps too boldly (?), we’re trying to create a scenario where creating these variations of UI doesn’t require a new element for every possible use case. In an attempt to not misuse, we see clear functional behavior that is consistent across a variety of UI with wildly different semantics. I’m personally totally open to a JS API for those, but I think prescribing semantics for just popup is going to lead to a dialog scenario. I think the trouble I’m having is that if the only way to standardize this behavior is through new elements for each, that’s going to be difficult, especially for scenarios like the listbox in select, or a context menu, where we want the functionality of the popup but as you call out, the semantics AND focus management are quite different from dialogs, tooltip, etc.

@domenic
Copy link
Contributor

domenic commented Oct 15, 2021

I’d be curious how “none” is a contradiction as far as implicit role, etc.

Sure. We already have two elements with "none" semantics: div and span. If people want to create elements with none semantics, then they should use div and span. Otherwise, new HTML elements should have new semantics.

Is the bar for any new element an applied semantic that maps to ARIA?

That's a good first approximation, IMO, but I wouldn't call it a hard-and-fast rule. In particular ARIA is mainly focused on roles that give different assistive-tech behavior, and "different semantics" are not 1:1 with "different AT behavior". For example, the <link> element has no ARIA role, but it has pretty clear semantics (linking to, or importing, an external resource). Similarly <input type=date>, <em>, or <br>.

Rather the relationship to ARIA I would promote is the one I alluded to in w3ctag/design-reviews#680 (comment), i.e. an implication of "the first rule of ARIA": we should never introduce a new HTML element which requires ARIA to function. So in particular, we should never introduce a new HTML element which we expect to, as a matter of course instead of as a special exception, be used with ARIA.

but if the ask is to revisit this as a JavaScript API then it would be great to see that presented as an alternative

I agree it would be great to see; that's why I brought up this issue, because we need the proposal proposal authors to investigate other ways of achieving the same goals that are congruent with the web platform design principles.

The intent of the element is to allow authors to compose UI without necessarily requiring JS. It seems reasonable to have that as an ask, but I’m certainly open to hearing why that’s not a feasible approach.

It's not feasible because, aside from div and span, HTML elements are a fundamentally about semantics, not behavior. You define a semantic for an element, and then derive behaviors that support that semantic.

If the goal of a proposal is to bring new behaviors, but no new semantics, then JS is the right manifestation for exposing them, not HTML.

(Ideally, those behaviors are done in a "layered" way (cf https://extensiblewebmanifesto.org/), so that JS already has access to these and the semantic elements just bundle them together into a declarative package with the right semantics. In the past that hasn't happened all that well; e.g., <details> was defined before the foundational layers (such as shadow DOM) were, and <dialog> is still defined without any other way of accessing the top layer (leading to the abuses of it that @mfreed7 mentions in w3ctag/design-reviews#680 (comment)). I don't think this kind of strict layering is required for all new elements, but it sure makes things nicer for authors in my experience.)

I think the trouble I’m having is that if the only way to standardize this behavior is through new elements for each, that’s going to be difficult, especially for scenarios like the listbox in select, or a context menu, where we want the functionality of the popup but as you call out, the semantics AND focus management are quite different from dialogs, tooltip, etc.

Yes, I think doing the right thing is hard :). But it's better than trying to ship popup, and over-claiming its applicability out of the box as something that works for menus, listboxes, tooltips, teaching UIs, content pickers, and form element suggestions. If in fact popup doesn't supply enough for those, but is only a building block, then I'd see two good paths:

  • Do the extra work to create proper elements for those, reusing elements of the popup proposal + whatever additions or changes are necessary for each case.
  • Try to move forward with a version of the popup proposal that is a behavior-only JS API, which can be applied to things like <div role="tooltip"> or <div role="menu"> while admitting that we haven't yet done the work to create full elements that embody the desired semantics and behaviors for tooltips/menus/etc.

@chrisdholt
Copy link
Collaborator

Thanks for the follow-up @domenic. Given this feedback @mfreed7, @gregwhitworth, @melanierichards we should probably prioritize this discussion at our next telecon.

I think many would like and prefer elements so that both the behavior AND semantics are available to web authors without having to include their own JS. I think that's the long-term ideal. With that said, my own selfish "immediate" needs and wants are the low-level JS API's. Some exist in some capacity already for the platform, but are not available to web authors. If I had to choose between the two today, I would take the JS API's as they'll better enable our building of custom elements with behavior we don't currently have access to today. If we had to "crawl, walk run" here, I'd personally prefer prioritizing the low-level API's and then leverage and reference those as part of specific custom-element proposals.

@yinonov
Copy link

yinonov commented Oct 15, 2021

Can such 👆 low level APIs integrate within built-in elements?
Should such "interior" component be exposed to web authors?
As mentioned, it doesn't have a semantic meaning on its own

@mfreed7
Copy link
Collaborator Author

mfreed7 commented Oct 15, 2021

So I understand the desire to "decompose" the current <popup> element proposal into lower-level APIs. And if that's possible, I can see the value in doing so. It would make it more straightforward to explain several new (potentially more-specific/semantic) HTML elements in terms of those APIs.

I'm curious about why this would be a Javascript API, though. It would seem more like a CSS primitive to me, since it deals with presentation: being on the top layer. Looking at the three functionalities provided in the original <popup> feature:

  1. Presentation on the top layer. This seems like it would best be expressed as a CSS property, no? Something like:
popup {
  position: top-layer;
}
  1. Light dismiss. Since putting it in the top layer is presentational, it would seem that taking it out would also be presentational, so another CSS property? Another concern: should it be possible to put something in the top layer without enforcing that it light dismisses? If so, it seems like a vector for abuse, but maybe not. If they are truly separate concerns, then perhaps something like (lots of bikeshed fodder here):
popup {
  light-dismiss: [none | esc | click-outside | scroll | other-top-layer-element | all]+
}
  1. One-at-a-time. As I included in #2 above, I think this has to be part of light-dismiss. If the other-top-layer-element value is provided for light-dismiss, then that element is "one-at-a-time". If not, then multiple of them can exist simultaneously in the top layer. That feels a bit magical, since at least for <popup>, there is a stack of popups, created by examining their anchor attributes and/or other elements' popup attributes, and thus allowing multiple nested popups. I don't know how to achieve that in a standalone API. Suggestions welcome.

@domenic
Copy link
Contributor

domenic commented Oct 15, 2021

Oh, sure, CSS is also reasonable; sorry for forgetting that option.

@chrisdholt
Copy link
Collaborator

Good point @mfreed7 - I do like the idea of keeping those in the presentation layer. I know a couple additional things which were discussed as well were transitions/animations and focus management. For animations, I think the web animations API would provide the needed support there already. For focus management we do have a proposal out for focusgroup which was already being discussed in coordination w/ <popup>. Regardless of where that ends up, I think the primary point is that the right low-level API's can make creating things which popup much easier on web authors.

Subjectively, I like the idea of exposing the top-layer and light-dismiss behavior via CSS more so than JS. It feels intuitive and I think there is value for not requiring JS to achieve these specific functionalities.

RE: Your question on light dismiss above - my initial reaction is to lean into allowing things at the top layer which do not light dismiss. I'd agree that it's a vector for abuse, but there are existing (and I think legitimate) patterns where a user is asked to make a choice or declaration in order to proceed into the main portion of the UI. I definitely want to be conscious of the ways folks might misuse this, but it seems like a miss if we require light-dismiss for anything in the top layer.

@mfreed7
Copy link
Collaborator Author

mfreed7 commented Oct 15, 2021

Good point @mfreed7 - I do like the idea of keeping those in the presentation layer. I know a couple additional things which were discussed as well were transitions/animations and focus management. For animations, I think the web animations API would provide the needed support there already. For focus management we do have a proposal out for focusgroup which was already being discussed in coordination w/ <popup>. Regardless of where that ends up, I think the primary point is that the right low-level API's can make creating things which popup much easier on web authors.

Good points - animations and focus need attention here also. For animations, while the Web Animations API can support animation use cases, it'd also be nice to support them with "plain" CSS also, without requiring JS. Perhaps a pseudo-class for being in the top layer?

  popup {
    opacity: 0;
    transform: translateY(50px);
    transition: all 1s;
  }
  popup:top-layer {
    opacity: 1;
    transform: translateY(0);
  }

The only thing missing here is that <popup> is made display:none !important when it is hidden. Perhaps if we just relax that to display:none (without the !important), then developer CSS can manage the entire show/hide lifecycle if they'd like? This might also obviate the need for beforeshow and show events to manage animations. But maybe I'm not thinking this through.

For focus management, there is already a discussion about expanding the delegatesfocus (name change TBD) attribute and behavior to other elements. And as you point out, the focusgroup attribute might be applicable here also? But beyond that API, perhaps the particulars of focus management are unique to each element? For the proposed <popup> element, the focus behaviors are:

  1. By default, showing a <popup> does not change the focus.
  2. If the <popup> has the delegatesfocus attribute, focus the first focusable descendent of the <popup>.
  3. If the <popup> or a descendent has the autofocus attribute, focus that element.
  4. Focus is never "trapped" inside the <popup>.
  5. Akin to <dialog>, focus is returned to the previously-focused element when the popup is hidden.

From the above, it seems like delegatesfocus is the only required new low-level primitive. But am I missing something?

Subjectively, I like the idea of exposing the top-layer and light-dismiss behavior via CSS more so than JS. It feels intuitive and I think there is value for not requiring JS to achieve these specific functionalities.

I'm glad. And it sounds like @domenic agrees. I would very much like to enable as much of this proposal without requiring Javascript.

RE: Your question on light dismiss above - my initial reaction is to lean into allowing things at the top layer which do not light dismiss. I'd agree that it's a vector for abuse, but there are existing (and I think legitimate) patterns where a user is asked to make a choice or declaration in order to proceed into the main portion of the UI. I definitely want to be conscious of the ways folks might misuse this, but it seems like a miss if we require light-dismiss for anything in the top layer.

I think I agree. The tricky thing will be specifying the rules by which the various participants in the top layer work together. For example, a full screen element likely should always remove other elements from the top layer. Similarly for a modal <dialog>. We just need to be careful about the interactions, and also make sure to specify this feature so that the UA is still in charge of the top layer, and can do the right thing when there is contention.

@gregwhitworth gregwhitworth added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Oct 20, 2021
@melanierichards
Copy link
Collaborator

Moving these capabilities into CSS (and HTML attributes where we’ve already said they could be extended to other elements) is an interesting line of thought. I’m considering what we might lose in the process, just for completeness:

  1. The popup content attribute, which enables another element to show the popup and establishes a controller / haspopup semantic relationship.
  2. autofocus behaviors when a popup is shown.
  3. Popup was proposed in large part to enable the listbox portion of a customizable <selectmenu>. Is the part attr enough for controller code to wire up the proper listbox semantics for that? Do we want to propose a <listbox> element?

Apologies if I’ve misinterpreted anything, reviewing this thread while brain-tired.

@melanierichards
Copy link
Collaborator

Also wanted to +1 on top-layer mgmt being more tricky if we go this route.

@bathos
Copy link

bathos commented Oct 21, 2021

I would love to see some of these capabilities exposed through CSS. We have a "building block" popup custom element that is conceptually very similar to the current proposal here - it has no semantics of its own and is used as part of tooltips, etc. But while powerful, it has always felt hacky because it's almost entirely concerned with presentation and most of its "API" is in CSS.

Snippet from our popup's docs: CSS API
## CSS API

The popover doesn’t have much CSS baked in but provides a number of hooks for
customizing. The most opinionated thing is that animations for expansion and
collapsing are provided by default and cannot be overwritten currently.

### ::part(popup) pseudoelement / fallback

The `::part(popup)` pseudoelement selector targets the styleable popup container
which is shown when the `<kn-popup>` is expanded. Most properties are fair game,
but some are blacklisted (e.g. display, width) because they would conflict with
the layout and positioning that `<kn-popup>` is providing.

Currently, we cannot use `::part`, so we provide a stopgap (whitelist instead
of blacklist) in the form of proxied properties:

- `--kn-popup-background`
- `--kn-popup-border`
- `--kn-popup-border-radius`
- `--kn-popup-box-shadow`
- `--kn-popup-padding`

Once ::part works in Safari & FF, we will transition to that API.

### --kn-popup-bleed-width

Syntax: `<length> | <percentage>`
Initial: `0px`

This creates a sort of ‘phantom margin’: the layout process, when selecting a
placement for the popup, will treat the containing boundaries being tested as if
they were smaller by this amount.

### --kn-popup-origin-gap

Syntax: `conterminous | <length>`
Initial: `0px`

As a length value, this specifies the distance between the origin and the popup
on the vertical axis (which could be above or below).

The keyword `conterminous` (look, it’s just perfect okay) produces no gap, like
`0px`, but has additional effects:

- Any corner of the popover which directly touches the origin box will have its
  border-radius set to zero. Keep in mind, again, that you do not always know
  in advance which corners these will be.
- The edge of the popover which contacts the origin box will be clipped such
  that box-shadows cannot extend past it.
- The expansion and collapse animations will scale only on the Y axis.

Note that the shadow clipping behavior may be unsuitable if your usage is one
that does not guarantee the width of the popover is not wider than the origin
element. For such cases, you may instead wish to set `--kn-popup-box-shadow` to
none and place a drop shadow filter on the entire element instead.

In the future, when `:state` is available, we may eliminate this option and
instead provide state pseudoclasses to allow the consuming elements to respond
to the various specific conditions mentioned here directly.

### --kn-popup-origin-priority

Syntax: `[ center | end | left | right | start ] || [ top | bottom ]`
Initial: `center bottom`

This sets the preferred origin point from which the popover should seem to open.

Vertical values are fairly straightforward. The _top_ value asks to prefer using
the top edge of the origin element as the origin from which the popover expands,
in this case upwards; _bottom_ is the opposite.

Horizontal values may require more clarification. As with _top_, _left_ asks to
prefer using the left edge of the origin element as the origin from which the
popup expands, but such popup is extending _towards the right._

```
  ______
 |______|___  <--origin element
 |          | <--popover is wider than origin. it is using a left origin point.
 |__________|

```

The `start` and `end` values behave the same as `left` and `right` in some order
which depends on local directionality.

The `center` option prefers alignment with the middle of the origin element, but
it cannot ‘swap’ with anything else. With the other four horizontal values,
their _opposite_ value is considered higher priority than falling back on
arbitrary shifting. To understand why this should be, consider if the previous
example’s left preference had been unsatisfiable:

```
      ______  |<--edge of screen — doesn’t fit opening from the left
     |______|_|_
     |        | |
     |________|_|
              |
```

If the prioritized value aligned with a side, it is taken to indicate a
preference not just for that specific side, but also for aligning with _a_ side
period:

```
     SWAP     |    |     SHIFT    |
      ______  |    |      ______  |
  ___|______| |    |   __|______| |
 |          | | VS |  |          ||
 |__________| |    |  |__________||
              |    |              |
```

### --kn-popup-vertical-overshoot

Syntax: `auto | none`
Initial: `auto`

If set to `none`, if neither side of the origin vertically permits the entire
intrinsic height of the popup content, rather than overshooting the edge of the
origin, the popup’s height will be constrained to the larger of the two available
areas.

### --kn-popup-width-mode

Syntax: `auto | min-origin | origin`
Initial: `auto`

The `origin` value expressly binds the width of the popup to the origin’s width.
If the popup content actually doesn’t fit, it will overflow with a horizontal
scrollbar.

Given that, `min-origin` is what it sounds like: the popup can be larger than
but not narrower than the origin.

Although this element ended up successful for us, we always have to choose between enabling a RAF loop or not to keep the position correct depending on the trade off between the cost of the loop (which triggers layout) and the likelihood that the positioning requirements / other dependent CSS may change dynamically:

Snippet from our popup's docs: ES API
## ES API

The `<kn-popup>` element has a very narrow ES API.

### `KnudgePopupElement.prototype.expanded`

Readwrite; boolean; reflects content attribute; default false.

### `KnudgePopupElement.prototype.rafEnabled`

Readwrite; boolean; default true; no content attribute.

While the popup is open, a rafloop runs which ensures the layout remains
coherent even if the conditions which led to the initial layout calculation on
expansion change. This recalculation must force native layout calc twice in
order to produce correct/deterministic results. On my comp this takes 1 to 2 ms,
which sounds small, but keep in mind this is within the frame, so you only get
16ms total and there may be other stuff running.

It would be unusual to have more than one popup expanded at a time; they are
almost always used in elements which are, though not modal, deactivated when not
focused, so it is unlikely to represent a bottleneck on desktop. At small
viewport sizes, most popup-on-desktop elements become full screen panels that do
not use `<kn-popup>`.

Altogether, it seems this is generally alright, but I wanted to leave an escape
hatch. There are some scenarios where you can be certain the checks are not
needed, and in resource constrained scenarios you may wish to enable and disable
it only in response to specific events.

> It’s possible, though I’m not certain, that the future Houdini Layout module
> will provide a way for us to achieve what we’re trying to do here off the
> main thread in a much more performant way. It does, at least, provide a simple
> way to ask for the intrinsic dimensions of children, which is exactly why we
> end up forcing extra layout calcs in the rafloop currently.

To me it seems like this strongly hints that the layout concerns in question more properly "belong" to CSS. We use a custom element for it right now only because of the current need for JS to achieve these positioning behaviors.

I'll include one last snippet from those docs for more context: they begin with our working definition of "popup" from initial design research. This may be useful for comparison to get a sense for the extent to which our element is or isn't similar to what's being proposed here since if they're more different than I realize, maybe the potential for CSSification is more limited than I'd hoped. Ours doesn't, for example, handle the "light dismiss" stuff - we leave that to the other elements that consume it since the particulars vary between usages.

Snippet from our popup's docs: "Characteristics of popups"
## Characteristics of popups

This is a summary of the fixed or notably variant characteristics which define
the category we’re calling _popup._

1. A popup has an expanded (open) state and a closed state. In the closed state,
   its content is not exposed visually or to the accessibility tree. In this
   sense, they resemble dialogs; they are transient overlays.

2. A popup has a special relationship to another element which is neither an
   ancestor nor descendent. This ‘origin element’, is available regardless of
   whether the popup is collapsed. In almost all scenarios, the origin element
   is focusable and participates in natural tab order.

   For example, the origin element of a classic select input would be a button,
   while the origin element of a typeahead select input would be a text input.

   a. Expanding a popup is typically achieved only through interaction with its
      origin element. Appropriate triggering events vary depending on higher
      level semantics.

   b. The origin element should implement aria-expanded and this should reflect
      the state of the popup. The origin element may also implement
      aria-haspopup, which would indicate a specific type of popup, but this is
      not always applicable.

   c. The origin element relationship is not just semantic: its position and
      dimensions have direct bearing on the layout logic of its popup.

   d. A popup may expand above (‘up from’) its origin element or below (‘down
      from’) its origin element. Expansion is typically animated and the conceit
      followed for animations is always emanation. Vertical direction depends on
      whether the origin point of the popup is along the top or bottom edge:

   e. An origin point exists along the top or bottom edge of the bounding box of
      the origin element. There are six possible origin points:

      ```
      x---x---x
      |       |
      x---x---x
      ```

   f. If the origin point is a corner, the vertical side of the popup which is
      not expressly aligned may not reach the opposite edge, or may be past it;
      however:

   g. The width of an origin frequently determines the exact width, the minimum
      width, or the maximum width of its popup.

   h. The origin element and the popup are sometimes presented visually as if
      they form a single connected structure. This is true of a select input for
      example, but not a tooltip. We call such popups _conterminous_ and they
      have certain common styling implications.

   i. The origin point of a popup is not fixed. Specific usages of popups always
      have have an origin _preference_ which can be expressed as a horizontal
      preference and a vertical preference. Numerous factors contribute to the
      actual origin selection.

      A. If the horizontal preference is not a corner, it is fixed. If it is a
         corner, it is _swappable_ (left may become right, etc). Vertical
         preference is always swappable.

      B. Directionality may impact horizontal preference.

      C. Min-content dimensions of the popup content determine whether there is
         available space for that content in a preferred area.

      D. The length between the top of the origin box and the top of an outer
         box, the length between the bottom of the origin box and the bottom of
         an outer box, the length between the left edge of the origin box and
         the right edge of an outer box, and the length between the right edge
         of the origin box and the left edge of an outer box will determine the
         areas within which placement may be tested.

      E. There are two outer boxes: one which determines the absolute limits
         of placement as physical fact, and one which is the intersection of the
         viewport box and the former. Placement within the viewport is preferred
         over other placements even if it requires swapping.

      F. A bleed width (‘must be this far from edge of outer box’) and a gap
         (‘must be this far from origin element in vertical axis’) may exist and
         may refine which placements are considered viable.

      G. While a popup is open, the previously selected origin is a factor. Only
         a more preferred origin may replace a previously selected origin unless
         the change is strictly required by the limiting box.

    j. An origin acts as an anchor, not a concrete position. This is observed
       when no candidate area is actually viable. Placement coordinates may then
       be adjusted, using the origin as a starting point, by the minimum amount
       needed to accommodate the actual popup dimensions, maxing at bleed,bleed
       in the limiting box’s coordinate system (beyond that point, the content
       would overflow).

3. The popup doesn’t imply specific semantics beyond those mentioned so far.
   Roles, aria attributes, and behaviors within the popup are defined by usage
   within a higher level element. However there are certain common patterns.

   a. In some cases, focusing the origin element is an interaction which expands
      the popup and focuses something within it. This immediate delegation
      creates the effect that the origin element is not an independent entity
      from the popup or that the popup itself participates in tab order. More
      often, the origin element is independently focusable from focusable
      elements within the popup.

   b. If a popup has interactive children, then when focus leaves the popup
      content, it closes. If the blur occurs without a related target, focus may
      return to the origin element. Focus also often return to the origin
      element in cases where the popup closes due to actions like the user
      making a selection.

   c. An exception to 3.b. is that if the blur occurs due to the window itself
      losing focus, the popup remains open. Returning to the window restores
      focus to the same element.

4. Popups are positioned and rendered above the origin element’s context. They
   don’t cause reflow, and, in native implementations, they may be able to
   render past containing boundaries that would clip HTML/CSS implementations.

   a. To remain accessible, popup content should generally immediately follow
      the origin element. (This is strictly necessary if the popup content is
      not itself focusable or does not have focus sent to it though interaction
      with the origin element.) This limits certain layout possibilities due to
      the container issue mentioned above, but it is *almost* always
      surmountable by having less `[REDACTED]` CSS.

@css-meeting-bot
Copy link

The Open UI Community Group just discussed https://github.com/openui/open-ui/issues/410.

The full IRC log of that discussion <una> topic: https://github.com//issues/410
<gregwhitworth> github-url: https://github.com//issues/410
<una> Github topic: https://github.com//issues/410

@mfreed7
Copy link
Collaborator Author

mfreed7 commented Oct 21, 2021

The minutes above seem to have missed the whole discussion, but this one looks complete:

https://www.w3.org/2021/10/21-openui-minutes.html

@mfreed7
Copy link
Collaborator Author

mfreed7 commented Oct 21, 2021

Per the meeting just now, I'm going to open a fresh issue (soon) for the question of whether/how to break apart the primitives of <popup> into separate low-level things. In the meantime, let's re-focus this issue on the OP - what does a <popup> mean, semantically?

@domenic
Copy link
Contributor

domenic commented Oct 21, 2021

Reading the minutes, I feel like some people pushing for "a generic semantic" were missing the points I made. Which is, if you want a generic semantic and not one of the existing semantics like listbox, dialog, tooltip, or menu, then the <popup> element must not be used for any of those purposes. Conversely, if you want an element that can be used for listboxes, dialogs, tooltips, or menus, then it must be usable for exactly one of those roles, not multiple. (Or, it can have some kind of switching like type="", but as mentioned in the TAG review that has not worked well in the past.)

I hope this helps people advocating for a generic semantic to better understand the issue in question.

@css-meeting-bot
Copy link

The Open UI Community Group just discussed semantics for popup.

The full IRC log of that discussion <hdv> topic: semantics for popup
<hdv> github: https://github.com//issues/410
<una> mason: one of the things we have is position: top-layer that lets you put any element into the top layer, the other is lightdismiss so what takes you out of it. These can concievably both be CSS props
<una> mason: the way the discussion is very much brainstorming at this point
<gregwhitworth> q+
<una> mason: in the popup spec there are a few things that are harder to make into seperate APIs (i.e. anchor, popup attribute that lets you declaratively open a popup)
<una> ack gregwhitworth
<chrisdholt> q+
<una> gregwhitworth: are you looking for opinions? concrete element vs. primitives
<una> masonf: q started as what is the semantic role for popup, need to find something that satisfies standards and a11y
<melanierichards> q+
<una> masonf: need general feedback
<una> gregwhitworth: we talked about this 3 years ago RE: what are the primary goals
<una> q+
<una> gregwhitworth: primitives or elements
<una> gregwhitworth: primitives can be an implementation detail at the end of the day
<una> gregwhitworth: the way I view the popup is that in and of itself it doesnt have that semantic meaning. it takes on semantic meaning when its utilized within something else
<BoCupp> q+ to say popup has semantics (I think they are menu semantics)... but maybe the name is too generic
<una> gregwhitworth: so im all for having as many of the primitives put together as possible
<una> gregwhitworth: but i dont want to backtrack where we're working on primitives consistently
<una> masonf: agree would love to get these things out, the idea is that shippign primitives willmake it easier to get the semantic things out
<flackr> +1
<una> masonf: would become easier to implement and spec bc they're based on things that already exist
<gregwhitworth> ack chrisdholt
<una> +1 to masonf
<una> chrisdholt: i would prefer to have a primitive bc I thihnk that attaching a role lets me ship elements tomorrow
<una> chrisdholt: the same time, underlying apis is core to our needs
<una> chrisdholt: independent elements seems to create a lot of overhead
<gregwhitworth> q?
<gregwhitworth> ack melanierichards
<hdv> q+
<una> melanierichards: we also lose things w/primitives: autofocus behavior
<una> melanierichards: do we have enough for select menu and controller code to apply semantics to listbox portion
<una> melanierichards: open to moving to CSS primitves that could unlock more scenarios
<una> melanierichards: as the need arises, add more semantics to UA stylesheet
<una> melanierichards: it was nice to have an element that comes packaged with all of these behaviors
<una> melanierichards: it will prob be very generic as listed in this issue
<una> melanierichards: its not like semantically the element is super interesting, but theres prior art in html
<una> melanierichards: not every html element has super unique semantic meaning
<BoCupp> q?
<flackr> q+
<hdv> ack una
<gregwhitworth> ack una
<una> melanierichards: i dont think thats a reason not to introduce the element but woul dbe open to exploring if issues w/tag
<hdv> una: I think I've always had the perspective, the more reusable the better, and the more declarative the better
<hdv> una: it's been hard to do popups because it requires JS to create… some of the things we got that have come out of using this element were great for CSS. Having some of these primitives will make it easier to build and implement the semantic <popup> element
<hdv> una: so I think we should focus on the primitives, and then it will be easier to get the HTML element out later
<hdv> una: and be useful for other parts of the platform
<hdv> una: we've broken out a number of things, like anchor and dismiss, we've thought that trough
<hdv> una: going down the route of primivites provides most flexibility and easiest implementation
<hdv> una: we also need to define primitive, HTML primivite and CSS primitive have different meanings how we're discussing them
<gregwhitworth> ack BoCupp
<Zakim> BoCupp, you wanted to say popup has semantics (I think they are menu semantics)... but maybe the name is too generic
<hdv> ack BoCupp
<una> BoCupp: popup has semantics
<una> BoCupp: if a modal dialog is displayed i would expect the popup disapear, but if a modal is displayed witha popup on top of it i would expect the modal to stay visible
<una> BoCupp: set of behaviors UA can enforce in top layer
<una> BoCupp: UA can coordinate the top layer
<tantek> +1 to una's points about reusability, more declarative, and defining primitives
<una> BoCupp: we want it to contain arbitrary content (context menu, teaching ui)
<una> BoCupp: they appear at different times, popup can be the right level of semantics
<una> BoCupp: dont have to take it so far as to declare details like menu and menuitems
<una> BoCupp: makes the popup elment less generic
<una> BoCupp: dont want to lose ability for browser to control top-layer interactions
<gregwhitworth> +1 to what Bo just said, I don't want another z-index world
<gregwhitworth> q?
<gregwhitworth> ack hdv
<gregwhitworth> q+
<una> hdv: ARIA notoriously hard for devs to get right
<una> hdv: browsers are the only ones who can ensure different levels are correct
<miriam> q+
<una> hdv: html would be super helpful for ensuring a11y
<una> hdv: would make it harder for implementors to make mistakes
<gregwhitworth> ack flackr
<una> flackr: i dont think these 2 ideas are at odds w/each other
<una> flackr: huge advantage i see here is not forcing us to define specific accesibility role for somethign that can be used on a lot of use cases
<BoCupp> q+
<una> flackr: per-element can decide on the a11y role
<una> gregwhitworth: my question is if you think theyre mutually exclusive
<una> I think they're not mutually exclusive, I just dont think we should not implement primitives in leu of elements
<una> ^ una
<una> gregwhitworth: im not disagreeing if we have the primitives it would make it easier to implement, im worried primitives will slow down shipping/the magic
<una> gregwhitworth:wed need to define every primitive fully and every usecase, leveraging that
<una> gregwhitworth: would gate release of those elements
<una> q+
<una> gregwhitworth: if we require primitives to be defined before elements, im concerned we're going to be 2-3 years out from shipping anything
<una> gregwhitworth: is that truly needed
<masonf> q+
<gregwhitworth> ack gregwhitworth
<gregwhitworth> ack miriam
<BoCupp> q?
<una> miriam: keep hearing an assumption that if primitives are in CSS they cant trigger ARIA & a11y
<una> miriam: in CSS overflow already does that: adds interactions an a11y features
<una> miriam: i think we need to keep pushing on that: have primitives in css that are already have a11y tied in w/o needing the a11y to be re-stated in HTML
<una> BoCupp: wanted to respond to flackr
<gregwhitworth> ack BoCupp
<una> BoCupp: if you have a primitive that says just show this in top layer, i do think they're mutually exclusiv
<una> BoCupp: you can have even more metadata exposed w/the primitives
<una> BoCupp: should it be modal, dismiss other dailogues, etc.
<una> BoCupp: options felt unweildly, might have a higher level property that says 'it should have popup behvaior', once we do that - semantics through name of element
<una> BoCupp: to make sure devs can get it right we want a packaged set of behaviors assigned to popup or menu
<una> BoCupp: UA can make sure special behaviors are honored
<gregwhitworth> ack una
<hdv> +1 to packaged set of behaviors to not rely on authors specifying eveything correctly
<hdv> una: not sure if implementing primitives will slow down implementing elements? we would need to figure out the primitives either way
<hdv> scribenick: hdv
<tantek> +1 una, will absolutely still need to figure out the primitives before launching the elements, otherwise the elements will be (even more) weird exceptions
<hdv> una: so I feel it is still going to take a long time before we have a semantic element that will have all the primitives built in, don't think it would necessarily be slowed down by discussing primitives first
<tantek> (we're *still* unwinding / backspecifying the legacy weird behaviors of HTML elements, e.g. in CSS etc.)
<melanierichards> q+
<hdv> una: declarative styling can still be accessible, and it should be
<gregwhitworth> ack masonf
<una> masonf: one thing ive realized from this discussion is we still want to ship an element called popup based on these behaviors
<una> masonf: still need to answer question on semantic roleof popup
<una> masonf: need to define popup and its pieces
<una> masonf: wanted to +1 we need to figure out pieces of toplayer interaction anyway to figure out popup, it might be easier to once we figure that out, isolate it
<gregwhitworth> q+
<una> masonf: i think we still can and even should spec toplayer access and css prop that leaves UA in control of top layer (i.e. interactions bw full screen, modal dialogs, and this new prop)
<una> masonf: we need to know what the interaction of these 3 things is - have some ideas for css property that gives this to you. Can set priority list
<gregwhitworth> ack melanierichards
<una> melanierichards: i'm not sure we're all talking about semantics and behaviors in the same way. Semantics = "what is this thing" & a11y mappings -- thats the core question from the thread
<tantek> +1 melanierichards, yes semantics and behaviors are different things. semantics are definitely tightly connected to a11y mappings, which may happen to have default behaviors
<una> melanierichards: definition will be generic like: window control w/ui automation
<chrisdholt> +1 to Melanie - I understood as the same which is where I found the sticking point. IE, we are getting an ask specifically around a11y mapping and our intent with popup as low-level is to support _many_
<una> melanierichards: resonate w/unas characterization of breaking down the problem into small chunks. Bo's point of certain things that arent resolved by focusing on primitives
<una> melanierichards: theres no CSS A11y model right now and how the two are linked
<una> gregwhitworth: just wanted to clarify im not opposed to primitives, i.e. anchor should exist on its own
<una> gregwhitworth: if we want to break popup apart, thats fine but we need to get a resolution on the threads question
<masonf> q?
<masonf> q+
<una> gregwhitworth: we want a popup element to exist, standardize generic primitives, and make standardization of popup elements easier
<una> gregwhitworth: i hear general support of primitives existance as well as the individual element
<una> gregwhitworth: want to resolve on where the folks working on popup are spending their time
<una> gregwhitworth: next discuss semantic role
<gregwhitworth> ack gregwhitworth
<una> masonf: ive seen/.heard a lot of +1s that we still want to ship popup element
<una> masonf: it is a question of a11y modeling/semantics
<una> masonf: then its just an ordering question
<una> masonf: lets resolve that we think thre is a semantic role for popup
<tantek> +1 masonf, agreed there are semantic roles here
<flackr> q+
<una> ACTION: next week we will resolve on a semantic role defitinition
<chrisdholt> q+
<BoCupp> I believe popup has a semantic role
<dandclark> q+
<gregwhitworth> ack masonf
<masonf> proposed resolution: <popup> has a semantic role, and deserves a place as an HTML element. TBD what the exact verbiage is for that semantic role.
<BoCupp> +1 to mason's proposed resolution
<masonf> +1 to hdv: we should get screenreader user input
<chrisdholt> q-
<una> dandclark: still confused what this means practically
<una> dandclark: theres a specific mapping for listbox, what does a new semantic mean
<chrisdholt> +1 with Dan, I don't think anything exists that wouldn't need to be overridden for a number of elements/usage
<una> flackr: i think whether we define css properties for these mgiht affect how universal the semantic meaning of popup needs to be
<gregwhitworth> ack flackr
<gregwhitworth> ack dandclark
<una> flackr: can create popup -like things w/other semantic props that might have different aria roles
<chrisdholt> q+
<gregwhitworth> ack chrisdholt
<una> masonf: popup would be more generic, and selecmenu would override it as a more specific role
<una> chrisdholt: is it acceptible to propose one and then override it in all these places?:
<una> gregwhitworth: popup is a div with additional behaviors
<una> chrisdholt: not sure semantic role adds value to popup
<una> chrisdholt: might add more confusion
<una> chrisdholt: +1 to div with behaviors
<BoCupp> also disagree that popup is best described as a div with behaviors
<tantek> it's ok to have "lightweight" or "broad" semantics rather than precise/narrow semantics
<melanierichards> to Una's point: https://github.com//issues/329
<BoCupp> +1 to tantek's "broad" semantics point
<chrisdholt> RE: Bo's disagreement, I think I'm specifically saying that an ARIA role doesn't fit here universally. Doesn't meant there aren't semantics, but I don't see an existing ARIA role that fits
<melanierichards> +1 to lightweight semantics on the element itself
<una> chrisdholt: my emphasis is there are semantics but i dont think there is a universal aria role that is applicable to popup
<tantek> I'd prefer no more (even nearly) non-semantic elements, as we've seen that's more confusing that helpful e.g. section vs div has only been a timewaster IMO
<tantek> s/that helpful/than helpful
<una> BoCupp: the mroe narrow we go the less useful the element is
<melanierichards> q+
<gregwhitworth> Zakim, close the queue
<Zakim> ok, gregwhitworth, the speaker queue is closed
<una> chrisdholt: if the ask isnt to provide an aria role, rather semantics for the interaction that seems reasonable
<chrisdholt> maybe a bad example as well - abbr?
<una> melanierichards: role dialog mappings in chore AM, i imagine popup is going to be very similar
<una> s/chore/core
<chrisdholt> has unique semantics based on context but I'm not sure it has an ARIA role, does it?
<una> melanierichards: can also do an excersize in all the different subtypes of popup
<tantek> +1 melanierichards
<una> RRSAgent, generate minutes please
<RRSAgent> I have made the request to generate https://www.w3.org/2021/10/21-openui-minutes.html una
<chrisdholt> On generic, the popup could be useful for composition - IE I have a menu and I want to wrap it in the popup and delegate focus to it. No reason to add additional semantics there...
<gregwhitworth> Zakim, end meeting
<Zakim> As of this point the attendees have been miriam, gregwhitworth, hdv, dandclark, chrisdholt, flackr, una, iopopesc, melanierichards, BoCupp, tantek
<Zakim> RRSAgent, please draft minutes
<RRSAgent> I have made the request to generate https://www.w3.org/2021/10/21-openui-minutes.html Zakim
<Zakim> I am happy to have been of service, gregwhitworth; please remember to excuse RRSAgent. Goodbye

@mfreed7
Copy link
Collaborator Author

mfreed7 commented Oct 21, 2021

Reading the minutes, I feel like some people pushing for "a generic semantic" were missing the points I made. Which is, if you want a generic semantic and not one of the existing semantics like listbox, dialog, tooltip, or menu, then the <popup> element must not be used for any of those purposes.

Thanks @domenic. I'm hoping you can clarify something for me. I'm not sure if there are strict definitions for "a generic semantic" and "non-semantic", but if those are interchangeable (and they seem like they are being used that way), then your logic above would say you're not allowed to use a <div> or a <span> to create those things either.

The general consensus at the meeting was that there is still a (strong?) desire to have a <popup> element which can be used for multiple purposes. It's like "a <div> with functionality" - that was said several times. Is there not a place for such a thing in the platform? I know you mentioned <details> as a bad example from the past, but it seems to be useful. What's the right way to go about a non-semantic element with functionality?

Having said all of that, I also don't exactly think <popup> is strictly non-semantic. Subject to lots of bikeshedding:

a <popup> is a lightweight, ephemeral piece of UI content that is displayed on top of page content.

Does that suffice for the semantic definition of <popup>?

@mfreed7
Copy link
Collaborator Author

mfreed7 commented Oct 21, 2021

What do folks think of these existing HTML elements?

  1. <article>: "Examples include: a forum post, a magazine or newspaper article, or a blog entry, a product card, a user-submitted comment, an interactive widget or gadget, or any other independent item of content."
  2. <nav>: "Common examples of navigation sections are menus, tables of contents, and indexes."
  3. <input>: Clearly an old and oft-complained example, but it can semantically represent all kinds of things.
  4. <dialog>: "represents a dialog box or other interactive component, such as a dismissible alert, inspector, or subwindow."

All of these, at least according to MDN, seem like "generic semantics" that can be used to represent a class of things. Some of those things above (e.g. <nav>) have sub-class elements (e.g. <menu>).

@domenic
Copy link
Contributor

domenic commented Oct 22, 2021

then your logic above would say you're not allowed to use a <div> or a <span> to create those things either.

No. As I mentioned in #410 (comment), it's precisely because we have div or span already to fill the role of non-semantic, needs-ARIA-to-work, that we can't create new elements in that space.

Is there not a place for such a thing in the platform?

There is not. The space of non-semantic elements which get semantics layered on top of them manually is taken up by div and span. Adding new ones breaks the first rule of ARIA and encourages people to create more "div soup" (just, in this case, "popup soup").

I know you mentioned <details> as a bad example from the past, but it seems to be useful.

Details has semantics. I mentioned it being a bad example of adding something without adding primitives. That badness is orthogonal to the semantic question.

What do folks think of these existing HTML elements?

These all have well-defined semantics. You can most easily see this by the ARIA mapping they have: article maps to role=article, nav maps to role=navigation, input has complicated mappings based on its attributes (e.g. role=checkbox, etc.), and dialog has role=dialog.

As I mentioned in #410 (comment), it's not a requirement that every element have an ARIA mapping to have reasonable semantics. But, as I said there:

we should never introduce a new HTML element which requires ARIA to function. So in particular, we should never introduce a new HTML element which we expect to, as a matter of course instead of as a special exception, be used with ARIA.

This is another way of phrasing what I said in #410 (comment), which is

Which is, if you want a generic semantic and not one of the existing semantics like listbox, dialog, tooltip, or menu, then the <popup> element must not be used for any of those purposes.

@hidde
Copy link
Contributor

hidde commented Oct 22, 2021

then your logic above would say you're not allowed to use a

or a to create those things either.

No. As I mentioned in #410 (comment), it's precisely because we have div or span already to fill the role of non-semantic, needs-ARIA-to-work, that we can't create new elements in that space.

Is there not a place for such a thing in the platform?

There is not. The space of non-semantic elements which get semantics layered on top of them manually is taken up by div and span. Adding new ones breaks the first rule of ARIA and encourages people to create more "div soup" (just, in this case, "popup soup").

To me, what could distinguish something like <popup> from <div>/<span> is that it could have things layered on top by the browser, automatically rather than manually through author-added ARIA. Things like ”this goes on top of other things / everything else”, focus management and setting the right ARIA properties could all break if authored on a div incorrectly or incompletely. It would benefit end users if such things can somehow be “built in”… my hope is that with its own element, such things could be implemented more robustly (by browsers).

As the popup research showed a variety of use cases, I agree such an element would need something to declaratively switch between types so that each type can have appropriate ARIA, focus management etc (as you and others say in w3ctag/design-reviews#680).

@domenic
Copy link
Contributor

domenic commented Oct 22, 2021

Yep, that sounds about right. With the slight modification to your last sentence,

I agree such an element would need something to declaratively switch between types so that each type can have appropriate ARIA, focus management etc (as you and others say in w3ctag/design-reviews#680).

that in the past we've found this kind of dynamic switching to go pretty poorly (i.e., the point the TAG made about how <input>'s type="" is not great design), so instead I'd suggest multiple distinct elements.

@gregwhitworth gregwhitworth removed the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Nov 3, 2021
@melanierichards melanierichards added the popover The Popover API label Nov 4, 2021
@openui openui deleted a comment from css-meeting-bot Nov 4, 2021
@melanierichards
Copy link
Collaborator

melanierichards commented Nov 4, 2021

To summarize the options on the table:

  • Introduce one <popup> element that can be further semantically enhanced by ARIA or by controller code when used in contexts like a customizable <selectmenu>.
  • Add a type attribute to <popup> to modify semantics (role).
  • Create multiple elements for different types of popups. Either:
    • Without an additional, generic <popup> element.
    • With an additional, generic <popup>
    • With the ability to add an attribute to <dialog> to make it behave like a generic <popup>.

Proposal

The landscape as I see it (and have heard agreement on it) is this: there is a base class of various concepts that we would call a "popup". These concepts share particular behaviors, e.g. top layer rendering, transience and light dismiss behaviors, mutual exclusivity (unless nested), etc.

Some of the sub classes of "popup" have stronger, more specific semantics:

  • Autocomplete windows, combobox listboxes, select listboxes are rougly equivalent to role="listbox"
  • Action menus: role="menu"

Other popups share these strong behaviors, but do not have particularly strong semantics. These would be roughly equivalent to role="dialog". Users should be aware that they are interacting with a temporal pane/dialog, but accessibility APIs might not have a more specific concept to map to:

  • Date/time popup pickers
  • Navigational menus (these are not action menus!)
  • Teaching UI
  • General-purpose popups that support fairly arbitrary content (check out misc popups research for a sampling on how these are used by design systems / component libraries).

In either case, content attributes can handle semantic relationships similar to aria-haspopup or aria-controls. Focusing here on the semantics/role of the thing itself.

What I would like to propose is that we:

  1. Create new elements for subclasses of popups that have strong semantics. We could also consider additional elements for subclasses of popups that may have very distinct behaviors and would warrant a separate carveout (I do not have candidates in mind for this but worth mentioning).
  2. Either provide a generic <popup> element for all the rest which don't have strong semantics, OR provide an attribute that could be added to <dialog> to make it behave like a <popup>.

Side note: we may want to consider an element for navigational menus, as authors would be likely to reach for a new menu element for these, and that would confer semantics that are inappropriate to nav menus.

Please note that I have not listed tooltip anywhere in this proposal. Tooltips have a specific behavioral set and content model expectations that make them distinct from popups, and we should explore "a customizable tooltip on the web platform" separately from this discussion.

@melanierichards melanierichards added the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Nov 4, 2021
@css-meeting-bot
Copy link

The Open UI Community Group just discussed Should there a `<popup>` element and what would be its semantic role?.

The full IRC log of that discussion <davidluhr> Topic: Should there a `<popup>` element and what would be its semantic role?
<gregwhitworth> github: https://github.com//issues/410
<davidluhr> masonf: Consensus seems to be "No, we shouldn't have a `<popup>`", and instead have menu, tooltips, etc.
<gregwhitworth> q?
<davidluhr> masonf: The feedback communicated that `<popup>` doesn't have a strong semantic role, and therefore we shouldn't have this new element.
<gregwhitworth> q+
<davidluhr> melanierichards: I joined this co-working session for that conversation. I wanted to take a look at any popup-looky-things and use established roles as a guiding force.
<davidluhr> melanierichards: There some popups that are going to correlate to existing roles, and others may not.
<davidluhr> melanierichards: Accross different design systems, there are generic popups that can accept any type of content. Others are more use-case driven.
<davidluhr> melanierichards: Surprising that feedback favored adding more, separate elements, since we originally thought we wouldn't be able to successfully add several new HTML elements.
<davidluhr> melanierichards: There are more tailored popups, but there's also a class of popups that's a glorified `<div>` with certain behaviors.
<davidluhr> bkardell_: There are plenty of landmark roles where there's a default, or derived by what it's inside of, or informed by the presence of another attribute.
<davidluhr> bkardell_: Can we not have a `<popup>` element, and a way of hinting it's role to communicate its intent. But what do we do if it's none of the above?
<davidluhr> melanierichards: Here is our existing research: https://open-ui.org/components/popup.research
<davidluhr> melanierichards: If we create a proper select, we can use listbox code for semantics. For other popups, the semantics will probably be similar to a dialog, but the behavior will be different enough that it'd be useful to have this element.
<masonf> q+
<davidluhr> melanierichards: Can we just add semantics with something like a `type` attribute, but people would agree that's probably gross.
<gregwhitworth> ack gregwhitworth
<davidluhr> bkardell_: So just connecting the ARIA role and nothing beyond that, that's the role of the AOM. It may look at related attributes. If it's just the role, then we may not have the same aversions as input with `type`.
<gregwhitworth> q+
<gregwhitworth> ack masonf
<davidluhr> masonf: Feedback was to perhaps use a non-modal dialog. What do people think about that?
<davidluhr> gregwhitworth: Maybe for historical reasons, there's desire to add an attribute for semantics.
<gregwhitworth> ack gregwhitworth
<davidluhr> bkardell_: We could have 5 different elements that imply a different role. This doesn't get into the same problems as input types.
<davidluhr> gregwhitworth: I don't get the pushback of having multiple elements.
<davidluhr> gregwhitworth: I'm in favor of having `<popup>`, `<tooltip>`.
<davidluhr> masonf: Is it possible to do some research on what roles libraries use for generic popups?
<davidluhr> bkardell_: Many of them don't have great ARIA.
<BoCupp> q+
<davidluhr> gregwhitworth: I don't buy the argument that if it doesn't have a role, it doesn't deserve to be an element.
<davidluhr> bkardell_: We could have an abstract `<popup>` and 5 different elements, with the only difference being the role they present.
<davidluhr> masonf: Are those 5 elements really the same? Focus behaviors? We may find that they're all subtly different and it'd take much more work to specify them all.
<davidluhr> bkardell_: I think they actually do have subtly different behaviors.
<gregwhitworth> ack BoCupp
<davidluhr> melanierichards: On the point of confusion, I wasn't thinking tooltips would be popups at all.
<melanierichards> q+
<gregwhitworth> +1 to BoCupp - it's the behavior switching that I care about here, not the roles
<bkardell_> q+ to ask for clariity on bo's key off of roles question
<davidluhr> @BoCupp: We don't Narrator to announce different roles, but they probably have different models and capabilities. A tooltip could have different triggers than a popup, such as appearing on hover.
<davidluhr> @BoCupp: Popup, to me, is not a generic thing. In my mind, it's distinct and the proper name for things like teaching UI and menus vs. Toast and Tooltip as a separate class.
<davidluhr> @BoCupp: So far, the popup has worked well for things like the select menu because it takes arbitrary content. But, if we compare it to toast and tooltip, it may seem to generic.
<davidluhr> masonf: What would you define a generic popup's role as?
<davidluhr> @BoCupp: Is there not a role just called popup? Should there be?
<davidluhr> masonf: There's a dialog with a modal or non-modal flag.
<davidluhr> @BoCupp: Popups are more transient than dialogs. Dialogs contain widgets and controls that users interact with (polar button options). It feels different than a popup, which has its own semantics and used for things like context menus and teaching UI.
<gregwhitworth> q?
<davidluhr> bkardell_: Looking at the research matrix, the examples you mentioned have 4 different roles listed there. Maybe we can define one thing, where the only difference is role.
<davidluhr> bkardell_: All the elements are there just for semantics and to drive a role. Many elements aren't interactive.
<davidluhr> masonf: I agree, many HTML elements are just there to communicate semantics.
<davidluhr> q+
<davidluhr> @BoCupp: What about <section> and <div>, is there a semantic difference?
<bkardell_> q-
<gregwhitworth> ack melanierichards
<davidluhr> melanierichards: You need to label `<section>` for it to have any semantics.
<gregwhitworth> Zakim, close queue
<Zakim> ok, gregwhitworth, the speaker queue is closed
<davidluhr> melanierichards: There's a monolithic concept called popup. There are subclasses of popup that have stronger semantics than misc. popup. And there are also other subclasses with more generic semantics.
<davidluhr> melanierichards: Maybe we could create new elements with strong semantics and keep `<popup>` for miscellaneous use cases. We're getting pushback on the miscellaneous element, and also pushback on having one element for all use cases that's enhanced with ARIA.
<davidluhr> melanierichards: I don't what to do with this. I could see us having 6 elements, with specific ones and `<popup>` as grab bag. Another solution is a dialog that takes an attribute to make it act like a popup. The popup would semantically be the same as dialog but have different behaviors.
<gregwhitworth> ack davidluhr
<gregwhitworth> davidluhr: a lot of component authors are seeking the more targeted usecase
<gregwhitworth> davidluhr: most devs are looking for functionality less so the accessibility
<gregwhitworth> davidluhr: I think that's a huge achievement and they'll pick the component for the functionality
<BoCupp> q+
<gregwhitworth> davidluhr: then you can have the generic option
<gregwhitworth> BoCupp: I think popup is a great grab bag
<davidluhr> @BoCupp: I like those last 2 summaries where popup doesn't block the creation of something like `<menu>`. I struggle with what you call something like teaching UI element? `<popup>` is a good outlet for that. Don't get rid of it just because we can conceive or more tailored "popups" as other elements.
<davidluhr> gregwhitworth: I'd love to hop find time to explore this further.
<gregwhitworth> Zakim, end meeting
<Zakim> As of this point the attendees have been flackr, masonf, miriam, bkardell_, gregwhitworth, BoCupp, melanierichards
<Zakim> RRSAgent, please draft minutes
<RRSAgent> I have made the request to generate https://www.w3.org/2021/11/04-openui-minutes.html Zakim
<Zakim> I am happy to have been of service, gregwhitworth; please remember to excuse RRSAgent. Goodbye
<eugene> Thought I had +ed in. Apparently I didn't. Oops.

@domenic
Copy link
Contributor

domenic commented Nov 4, 2021

Create new elements for subclasses of popups that have strong semantics. We could also consider additional elements for subclasses of popups that may have very distinct behaviors and would warrant a separate carveout (I do not have candidates in mind for this but worth mentioning).

This makes sense to me, although I don't understand the distinctions you're making between "strong semantics" and "very distinct behaviors". But +1 to the general idea of building semantic elements with their own custom behaviors.

So far it sounds like you have listbox and menus; I know those behave differently in terms of focus (listbox = focus first element, menu = focus the menu), and probably other things as well.

Either provide a generic <popup> element for all the rest which don't have strong semantics, OR provide an attribute that could be added to <dialog> to make it behave like a <popup>.

Based on my reading of the "Other popups share these strong behaviors, but do not have particularly strong semantics" examples, it seems like a dialog extension. E.g. the ARIA best practices document lists date/time popup pickers as using the dialog role and dialog's focus-the-first-focusable-element focus behavior (direct link), but also shows light dismiss behavior. So e.g. <dialog lightdismiss> or <dialog>.show({ lightDismiss: true }) might be good ways of implementing that.

It might be worth doing more research or consulting with accessibility teams on what the best presentation is for the other "other popup" behaviors, but I suspect non-modal dialog is the right choice in general.

@domenic
Copy link
Contributor

domenic commented Nov 4, 2021

Navigational menus (these are not action menus!)

Interestingly it looks like according to the ARIA folks you use the same accessibility markup for both types of menus: https://www.w3.org/TR/wai-aria-practices-1.1/#menubutton

We could have separate semantic elements if we think the semantic and behavioral differences are important (as I assume the capitalized "NOT" indicates), e.g. <navmenu> and <actionmenu>. They would have the same accessibility roles and setup though it seems.

@melanierichards
Copy link
Collaborator

melanierichards commented Nov 4, 2021

This makes sense to me, although I don't understand the distinctions you're making between "strong semantics" and "very distinct behaviors".

I don't have an example of "very distinct behaviors", just heard murmurs that some folks might want to cordon off popups that feel particularly behaviorally distinct, so want to acknowledge that possibility.

It might be worth doing more research or consulting with accessibility teams on what the best presentation is for the other "other popup" behaviors, but I suspect non-modal dialog is the right choice in general.

Agreed. In UI Automation anyway, I anticipate the Pane control type being most appropriate for many of these, which is how dialog maps into UIA. Other APIs might have a couple other options though.

Interestingly it looks like according to the ARIA folks you use the same accessibility markup for both types of menus: https://www.w3.org/TR/wai-aria-practices-1.1/#menubutton

Currently documented as such, but there is not consensus on the appropriateness of this. UIA certainly expects menus to be an array of actions as opposed to navigational links (I'm referencing UIA here because it's the API I'm most familiar with). Anyway, this is a little in the weeds and we can take these choices one by one.

@mfreed7
Copy link
Collaborator Author

mfreed7 commented Nov 4, 2021

Thanks for the comments @melanierichards and @domenic.

It sounds like we have agreement that there should be separate, more specific elements (eventually) for some roles like listboxes and menus. But the big sticking point is the more general purpose element that doesn't fit into one of these more specific elements.

From this comment:

Interestingly it looks like according to the ARIA folks you use the same accessibility markup for both types of menus: https://www.w3.org/TR/wai-aria-practices-1.1/#menubutton

We could have separate semantic elements if we think the semantic and behavioral differences are important (as I assume the capitalized "NOT" indicates), e.g. <navmenu> and <actionmenu>. They would have the same accessibility roles and setup though it seems.

...it sounds like it would be ok to introduce two different elements that both map to the same accessibility role? That leaves open the possibility of having a <popup> element that maps to the "dialog" role (with aria-modal=false), is that right?

This, I believe, would be beneficial as compared to something like <dialog isreallyapopup>, because many facets of <popup> don't apply to dialog. These include things like the anchor attribute, which would need to be present but unused on the HTMLDialogElement IDL. This is part of what is so painful about <input type=foo> - the attributes list is quite convoluted.

I can't help but draw the parallel to the <section> element. Its description says it is a "generic standalone section of a document, which doesn't have a more specific semantic element to represent it". MDN further gives the example that a navigation menu should use a <nav> element instead, but that search results or map displays should use <section> since they don't (yet) have an element. I would think <popup> is similar - it provides the general case, to be used unless there's a better, more-specific element like <listbox> or <actionmenu>.

@domenic (and any others that want to participate), it'd be great if you could potentially join in the discussion at the next OpenUI meeting when this issue is on the agenda. We'd love to come to a consensus on the best way forward, and we need your help!

@domenic
Copy link
Contributor

domenic commented Nov 4, 2021

...it sounds like it would be ok to introduce two different elements that both map to the same accessibility role? That leaves open the possibility of having a <popup> element that maps to the "dialog" role (with aria-modal=false), is that right?

Yes, that sounds reasonable. As long as people never use it for listboxes, menus, or tooltips, and the spec makes it clear doing so is invalid!

I'd suggest a name like <popupdialog> in that case.

@domenic
Copy link
Contributor

domenic commented Nov 4, 2021

Although on further thought, it'd be helpful to get a more detailed account of

many facets of <popup> don't apply to dialog

I.e., I think anchored non-modal dialogs are pretty common, so making anchor="" work with <dialog> in that way seems very reasonable to me.

In other words, I think a comprehensive pro/con comparison of <popupdialog> vs. <dialog lightdismiss> or similar would be a good next step. How many of the popup behaviors could work with non-modal <dialog>? With modal <dialog>? How much functionality would end up duplicated between <dialog> and <popupdialog>, if they were separate? Etc.

@mfreed7
Copy link
Collaborator Author

mfreed7 commented Nov 11, 2021

Thanks! It sounds like we're making progress. So here's a proposed way forward, upon which it sounds like we might be in rough agreement:

  1. The plan is still to have a "general purpose" element that maps to the "dialog" role with aria-modal=false.
  2. Since this new element is similar to a dialog and maps to that AT role, it likely should have a name that indicates this. So something like <popupdialog> or <transientdialog>? I can open an issue for naming. For the rest of this post, I'll use <popupdialog>.
  3. This new element will have a semantic description something like "a transient non-modal dialog box, which is displayed on top of all other content. Popups are necessarily transient, such that only one is open at a time, and taking action elsewhere hides the popup.". (Improvements to this description would be welcome.)
  4. This new element must only be used for dialogs, and specifically cannot be used if there is a more specific semantic element that applies. The spec might or might not contain a specific list of elements or element types, but generally we should acknowledge that this "general purpose" element shouldn't be used in some specific cases, e.g. listboxes, menus, tooltips, and toasts. There is some precedent to this type of proscription, with the MDN description for <section>.
  5. We (OpenUI) need to make a more concrete plan for which more-specific elements make sense to build eventually, so that the point above isn't nebulous for new users of the element. A very tentative starting point would be that we should have dedicated elements for <listbox>, <actionmenu>, <tooltip>, and <toast> (!). Maybe also a <navmenu>? The <listbox> element might need to be worked out sooner, so it can be used for the <selectmenu> proposal. If this post gets general agreement, I can open a separate issue to brainstorm the appropriate element list.
  6. I don't believe we need to wait until specific proposals exist for all of the elements in the point above. A concrete plan with a specific list of elements should suffice to unblock <popupdialog>.
  7. Finally, we need to go back over the <popupdialog> proposal to see if any parts of the proposed behavior no longer apply, or are different, in a context where some use cases, e.g. <listbox> or <actionmenu>, exist. For example, do we still need delegatesFocus/autofocus behavior? (We might, but it is worth asking.)

Separately from the above points, I also totally agree with your point that we should put together a point-by-point comparison of <popupdialog> and non-modal <dialog>, both to point out how they are different, but also to see where there might be commonalities that can be shared between them. The explainer actually does have something of a comparison like this, but it would be good to take a fresh look.

@domenic
Copy link
Contributor

domenic commented Nov 11, 2021

That sounds great to me!

@zcorpan
Copy link
Contributor

zcorpan commented Nov 11, 2021

@mfreed7 @domenic I like the direction of separate elements for separate use cases / roles.

They can still share some (or most, or even all) of the APIs and attributes, similarly to e.g. <audio> and <video>.

@mfreed7
Copy link
Collaborator Author

mfreed7 commented Nov 12, 2021

I've opened issues for bikeshedding a new element name, and the list of proscribed element types.

@scottaohara
Copy link
Collaborator

is listbox only being considered as a popup element? apologies if i have missed this answer somewhere else. would definitely be useful as a non-popup as well.

Regarding the idea that a popupdialog would map to a non-modal dialog... while there would be overlap there, the transient nature of it likely means we need a variation to the mapping. Something different about it to let screen reader users know "this is a dialog (<dialog>), but this (<popupdialog>) is a dialog that is going to disappear on you". There are already some mixed expectations for non-modal dialogs (should tab key be able to exit, or should it be trapped in the non-modal dialog and another key, F6 for instance, be used to cycle between open dialogs / the primary document). I am not looking for an answer to that here... but I am calling it out as to why I don't think this can just be mapped to a non-modal dialog.

i very much like the idea of the separate elements approach, but it makes me still wonder what a generic popupdialog would be used for? And I say this because every time I think of something that could go in it (that isn't already called out in the excluded types issue), I then also think "well, that would be better as a 'popuplist' or a 'popuptoolbar', or a 'popupgrid'. I'm not actually making element suggestions there... just thinking aloud of where is the line?

I then also wonder if there are certain types of components that a popupdialog should not be used for, then there would also need to be a list of elements (and roles) that would not be allowed as descendants of popupdialog as well. e.g., if it can't be a listbox, then i would assume <select multiple> could not be a descendant?

@css-meeting-bot
Copy link

The Open UI Community Group just discussed https://github.com/openui/open-ui/issues/410.

The full IRC log of that discussion <melanierichards> topic: https://github.com//issues/410
<hdv> github: https://github.com//issues/410
<hdv> masonf: this issue is around the semantic meaning for <popup>, there's been a lot of discussion, I will jump to kind of what we arrived at
<hdv> masonf: there is a list of things for which semantically a generic purpose popup element doens't make sense, but we'd still like a general purpose element for other uses
<hdv> masonf: this general purpose element would be mapped to an accessible role for non modal dialog
<hdv> masonf: there has been some discussion on the thread… there are a few points raised by scottohara, like that non modal dialog may not be the right role
<hdv> masonf: I wonder if we are sure these are distinct behaviors, but let's discuss
<hdv> masonf: there were also other questions about listbox, one of the proposed non general case elements
<melanierichards> q?
<hdv> masonf: and another question around which elements can be descendants of dialog elements
<melanierichards> q?
<hdv> domenic: I think the biggest point I'd like to get into is 'what is this actually going to be used for?' I saw a lot of things in the thread it is not used for… I saw teaching use case
<hdv> scottohara: for many of the things, I wonder why would we not have a specific element for that, or just a non modal dialog
<hdv> scottohara: picture element is a container element, meant to represent child sources… is that something <popup> could be? so it has to have children, it has no meaning in and of itself
<hdv> scottohara: so you could have a popup element with a listbox inside of it, and then it would be a listbox popup… so by itself, if there's no children, it means nothing
<hdv> domenic: interesting analogy… picture has other reasons why it exists
<hdv> domenic: the <picture> element is a package deal, like you have to have a child there for it to work
<hdv> masonf: so what goes into the <picture> element would be semantic elements
<melanierichards> q?
<hdv> domenic: I wonder if they share a lot of the behaviours though… like listbox isn't very similar to others… we've talked about that a bit on the thread too
<hdv> scottohara: that makes sense to me
<hdv> scottohara: I see a lot of potential for misuse for this generic element… like, cases where you need a listbox element, but just throw a select multiple inside of it… 
<hdv> scottohara: that wouldn't meet our requiements, probably
<hdv> s/requiements/requirements
<hdv> masonf: one of the nice things, accessibility aside, the nice part of having one element that encapsulates the behaviours is nice in a lot of respects, because it separates the behaviour from the semantics
<hdv> masonf: a behaviour-only non-semantic element that contains a semantic-only element, I really like that
<hdv> domenic: I still think it is the opposite of nice
<hdv> domenic: there is a lot of stuff that is different between these… and then there's a lot of extra knobs like delegatesfocus and others that could make it hard to use from a developer's perspective
<hdv> scottohara: I think I agree to that… these could have different behaviours and features… also could have quite different UIs
<hdv> scottohara: there could be different interaction models that need to be respected
<hdv> masonf: both fair points for sure
<hdv> domenic: if you wanted a generic container element… maybe you could pick one behaviour
<hdv> domenic: so it wouldn't come with focus behaviour or light dismiss
<hdv> domenic: and that stuff would be in the semantic element child
<hdv> scottohara: sounds good to me, the keyboard behaviour could also go to the child element
<hdv> domenic: I still think it would be nice to have one element rather than having to nest two, for developers. I liked Simon Pieter's analogy to audio and video, they have very similar behaviours but are separate elements
<hdv> melanierichards: there is some research on this, carving out semantic elements that have specific behaviours. Still feel there could be one popup elements where we pick a specific behaviour
<melanierichards> q+
<melanierichards> q-
<hdv> melanierichards: regarding listbox… we are working on a customisable select menu too
<hdv> melanierichards: thanks for the great discussions… how do we want to make progress from here?
<hdv> masonf: I think we need to spec out the different types and the different behaviours, then come back here when we have that?
<hdv> masonf: I can take an action to get that discussion started… are there other things that would help that discussion?
<hdv> domenic: I found a list of use cases that melanierichards posted earlier in the discussion. I would like to hear some discussion about whether there is something generic between these… what would be left if we carve out specific elements, what would be left for a generic element?
<hdv> scottohara: what is a navigational menu, just a list of links? A teaching UI could be a list of non modal dialogs?
<hdv> scottohara: I am not sure if it needs a special element?
<hdv> domenic: agreed may be good to compare these to find out if there is something generic
<hdv> scottohara: something you may have talked about before… is popup behaviour maybe an attribute that can go on different elements?
<hdv> scottohara: that way we may not need an extra element?
<hdv> masonf: in the thread I described CSS that could do something like this too
<hdv> masonf: it is tricky to describe how each of them could interact with other elements
<hdv> scottohara: ok but then we could describe which elements allow for it and which not (eg you wouldn't have an article popup)
<hdv> masonf: I think the list of elements may become quite long, you might want it on many elements
<melanierichards> q?
<hdv> scottohara: right but it may end up being one list of another
<hdv> s/of/or
<hdv> melanierichards: ok so we have an action to come up with a list of different use cases and behaviours and how they compare
<hdv> masonf: I think the answer to the question of whether there should be an element or an attribute, we may be easier to find that answer after we created the list?
<scottohara> +1 on investigation of elements
<hdv> melanierichards: ok, we could stop this discussion if we all agree on creating a list
<hdv> masonf: I created an issue and will reuse that for brainstorming about these things
<hdv> RRSAgent, make minutes please
<RRSAgent> I have made the request to generate https://www.w3.org/2021/11/18-openui-minutes.html hdv
<melanierichards> Zakim, end meeting
<Zakim> As of this point the attendees have been hdv, tantek, melanierichards, scottohara, miriam
<Zakim> RRSAgent, please draft minutes
<RRSAgent> I have made the request to generate https://www.w3.org/2021/11/18-openui-minutes.html Zakim
<Zakim> I am happy to have been of service, melanierichards; please remember to excuse RRSAgent. Goodbye
<melanierichards> RRSAgent, please part
<RRSAgent> I see no action items

@gregwhitworth gregwhitworth removed the agenda+ Use this label if you'd like the topic to be added to the meeting agenda label Dec 1, 2021
@mfreed7
Copy link
Collaborator Author

mfreed7 commented Apr 7, 2022

I'm closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
popover The Popover API
Projects
None yet
Development

No branches or pull requests