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

How to spec user interaction for select #10762

Open
josepharhar opened this issue Nov 14, 2024 · 25 comments
Open

How to spec user interaction for select #10762

josepharhar opened this issue Nov 14, 2024 · 25 comments
Labels
topic: select The <select> element

Comments

@josepharhar
Copy link
Contributor

josepharhar commented Nov 14, 2024

What is the issue with the HTML Standard?

As part of customizable select, there is desire to add something to the spec that explains how the user can interact with the select element. There is already some paragraphs related to choosing options, which basically just says that input and change events should be fired after the user chooses an option.

Potential actions:

  • Activating the button to toggle the picker open/closed
  • Choosing an option
  • Navigating between options (arrow keys)

Potential requirements:

  • What events are fired in each case?
    • Are we allowed or disallowed from talking about pointerup, pointerdown, mouseup, mousedown, keyup, keydown, keypress, and click in the spec?
    • Can/should we talk about the details of these events, such as what the key property of a relevant KeyboardEvent should be?
  • Is there a consistent set of events? Or might they be different depending on input mode or platform? (keyboard vs mouse)
    • Should we provide a list of different events that input modes or devices can choose from?
  • What does calling preventDefault on any relevant events do?
  • What elements are the events fired on?
    • For actions related to options, I would hope that we can fire the events on options rather than the select element.
    • More generally, I don't want to change the fundamentals of how keyboard and mouse events work in web content inside the picker popover in the browser.
  • Making everything the same for appearance:auto and appearance:base
    • [select] keyboard behavior openui/open-ui#1087 (comment)
    • I could imagine that it could be hard or not compatible to patch this event behavior into native pickers, but who knows.
    • There are also platform specific variations, like the selection-follows-focus and click-and-drag behaviors for select elements in chrome on windows and linux.
  • Ending up with some way of opening the base appearance popover without user activation, whether that's select.click() or select.showPicker()
  • Hopefully we can end up with something that is actually testable in WPT with existing things like test_driver.click() and test_driver.Actions(), so that all the tests I've written so far don't just become non-interoperable suggestions.

Potential solutions:

@josepharhar josepharhar added the topic: select The <select> element label Nov 14, 2024
@josepharhar
Copy link
Contributor Author

@domenic @annevk @smaug----

@annevk
Copy link
Member

annevk commented Nov 14, 2024

I think it's important context to state why this is important: the popup is not script-observable without appearance: base. E.g., keydown is not fired when cycling through options.

@josepharhar
Copy link
Contributor Author

At whatnot we discussed this, and it sounded helpful to start by providing a list of situations where preventDefault would change the behavior. There was also a discussion about reusing the popovertarget activation behavior to open the popover picker.

@annevk
Copy link
Member

annevk commented Nov 15, 2024

FWIW, when I played with this yesterday it seems that pressing the down arrow on a closed select element does fire a keydown event on the select element (and opens the picker). So that at least is already exposed regardless of appearance.

@smaug----
Copy link

Sure, the focus is in that case on select. In the new case the focus is on option elements.

@josepharhar
Copy link
Contributor Author

Perhaps we can make something like this paragraph that's already in the spec? https://html.spec.whatwg.org/multipage/form-elements.html#concept-select-pick

How does this sound for opening the picker?

If the select is being rendered as a drop-down box, then the user agent should allow the user to open the picker. Opening the picker will either fire a corresponding mousedown or keydown event on the select element. Calling preventDefault on either of these events will prevent the picker from opening. Otherwise, the picker is opened.

@smaug----
Copy link

smaug---- commented Dec 2, 2024

One thing to define is how click works on options - current Canary dispatches click to the common ancestor of option and whatever happens to underneath the popup. I would expect click to be dispatched to the option element itself. So, activation behavior, not something else. I think the spec pr even expects this, so it might be an implementation issue, but are there tests for this?

If option uses activation behavior, how should it behave if other elements with activation behavior were inside it? Or should option somehow have interactivity: inert; for its content?

@smaug----
Copy link

I think the expected behavior from user's point of view when dealing with Home/End/PgDn/PgUp is that those would change focus between option elements, similarly to arrow keys. Maybe some of that could be left up to the implementation, though when testing Canary, which doesn't deal with those, select does feel a bit broken.

Do we need to consider anything special for mobile? Currently select popup is a native popup there, I think in all the browsers.

@josepharhar
Copy link
Contributor Author

One thing to define is how click works on options - current Canary dispatches click to the common ancestor of option and whatever happens to underneath the popup. I would expect click to be dispatched to the option element itself. So, activation behavior, not something else. I think the spec pr even expects this, so it might be an implementation issue, but are there tests for this?

If option uses activation behavior, how should it behave if other elements with activation behavior were inside it? Or should option somehow have interactivity: inert; for its content?

Yeah I used activation behavior in the spec PR, but based on feedback from @domenic it sounds like we shouldn't be using activation behavior and I need to replace that with whatever we come up with in this thread.

The chromium implementation currently uses the default event handler of the mousedown event on option elements (as opposed to click, which would be the "activation behavior" concept). We could also make it mousedown instead if that's better.

I'm not seeing any click events get dispatched to stuff underneath the popup though, just mouseup which makes sense because chromium currently closes the picker on mousedown on the option. Are you seeing something different?

I think the expected behavior from user's point of view when dealing with Home/End/PgDn/PgUp is that those would change focus between option elements, similarly to arrow keys. Maybe some of that could be left up to the implementation, though when testing Canary, which doesn't deal with those, select does feel a bit broken.

Thanks for pointing this out, I filed a bug: https://issues.chromium.org/issues/382101095

Do you think we should add an abstraction in the spec for each of these actions?

Do we need to consider anything special for mobile? Currently select popup is a native popup there, I think in all the browsers.

We are not planning on doing anything special for mobile, and we want to use the new popover picker when the developer asks for it on mobile. In OpenUI we previously discussed adding a media query to change what the default styles are on mobile, but decided against it because it would make it hard for the developer to reset it.

@smaug----
Copy link

smaug---- commented Dec 3, 2024

Click event is dispatched to the common ancestor of *down/*up.
https://mozilla.pettay.fi/moztests/select_new.html (just an ugly page to try out various things) shows that body element gets the click. Open the web console to see relevant logs. The element underneath the option element gets the *up event and the common ancestor then the click event.
(The weird contenteditable test in the page doesn't seem to affect click target.)

Why wouldn't we use activation behavior for option?

@josepharhar
Copy link
Contributor Author

Thanks for taking a look and making the demo page!

shows that body element gets the click

I see. I can also see that clicking and dragging on other elements in the page still fires a click event on the body element, as well as clicking a popovertarget button:

<body onclick="console.log('body onclick')">
<button popovertarget=popover>invoke popover</button>
<div popover=auto id=popover>popover</div>

What mechanism could prevent the body element from getting a click event when clicking an option?

The element underneath the option element gets the *up event and the common ancestor then the click event.
(The weird contenteditable test in the page doesn't seem to affect click target.)

I think that I should move from a mouseup handler for options to mousedown or click (click would be activation behavior) to make this better.

Why wouldn't we use activation behavior for option?

I think that using activation behavior for option elements is fine if it gets agreement. Do you also have opinions on whether we should use activation behavior for the select element itself to invoke the popover, and whether that should match invoking the appearance:auto popup? I'd also like to hear from @domenic on this.

@josepharhar
Copy link
Contributor Author

Based on the discussion at whatnot I added the paragraph I mentioned earlier in this thread as well as a paragraph with two algorithms for using the arrow keys to move focus between options to the PR here: #10629

@domenic
Copy link
Member

domenic commented Dec 6, 2024

Why wouldn't we use activation behavior for option?

I think that using activation behavior for option elements is fine if it gets agreement. Do you also have opinions on whether we should use activation behavior for the select element itself to invoke the popover, and whether that should match invoking the appearance:auto popup? I'd also like to hear from @domenic on this.

In our internal discussions, I was trying to represent what I thought was the general standards-community consensus, that activation behavior is unfortunate because it breaks https://dom.spec.whatwg.org/#action-versus-occurrence . (I.e., it inverts control such that element.dispatchEvent(new MouseEvent("click")) can cause something to happen.) So, I thought we would prefer to avoid it for new features.

But it's possible that people prefer consistency with the old, problematic stuff. I have no personal objection to using activation behavior, if the consistency gain is deemed important.

I do wonder what we're being consistent with, though. I don't think that in today's appearance: auto <select>, doing selectEl.dispatchEvent(new MouseEvent("click")) or optionEl.dispatchEvent(new MouseEvent("click")) will actually drive the UI. So I'd be surprised if we wanted to start making that work for appearance: base <select>s.

I'm curious on @annevk's take.

@annevk
Copy link
Member

annevk commented Dec 6, 2024

I worry a bit about implications for things like https://html.spec.whatwg.org/#activation. We'd have to split in "historical activation behavior" and "revamped activation behavior" or some such. In general I would not be opposed trying to move away from it, but it would need careful testing.

@josepharhar
Copy link
Contributor Author

Ok, for now I'm going to make option element activation not use activation behavior and look for "mouseup" because:

  1. To be consistent with the rest of the new text we are adding which does not use activation behavior
  2. To fix some of the issues that @smaug---- bought up earlier about click and mouseup being unexpectedly sent to other elements
  3. To support the click and drag behavior which is already supported by firefox and chromium on windows and linux (not sure about macos).

I added this to the base appearance spec PR by changing this paragraph.

@Permik
Copy link

Permik commented Dec 9, 2024

(not sure about macos).

Yeah, drag clicking dropdowns works on macos also :)
It's a pretty universal UX-pattern that almost got lost during the generational change.

@annevk
Copy link
Member

annevk commented Dec 9, 2024

@josepharhar how will you take care of the requirements I pointed to? Abstract this in some way so that they can also apply to certain elements without activation behavior?

Also, how does that provide keyboard access?

@smaug----
Copy link

Related to #10762 (comment) doesn't that lead to firing click on option element after the value has been changed and popup closed? Isn't that a bit odd behavior for click?

@josepharhar
Copy link
Contributor Author

I worry a bit about implications for things like https://html.spec.whatwg.org/#activation. We'd have to split in "historical activation behavior" and "revamped activation behavior" or some such. In general I would not be opposed trying to move away from it, but it would need careful testing.

how will you take care of the requirements I pointed to? Abstract this in some way so that they can also apply to certain elements without activation behavior?

So we should add documentation about this behavior for select in the #activation section? I could try adding a paragraph about "revamped activation behavior." Would you prefer to reuse regular activation behavior and use click events for everything?

Also, how does that provide keyboard access?

I included affordances for keyboard access by listing keydown in addition to mousedown or mouseup events for each of the new paragraphs I added.

@josepharhar
Copy link
Contributor Author

josepharhar commented Dec 10, 2024

Related to #10762 (comment) doesn't that lead to firing click on option element after the value has been changed and popup closed? Isn't that a bit odd behavior for click?

Yes, looks like you are correct.

I just tested out listening to the click event instead of mouseup, and it breaks the click and drag use case because click fires on select instead of the option because that is where the click-and-drag started.

I think there are pros and cons for each and it sounds like there are varying preferences, so I'm going to write out what I'm hearing so far:

Listen to click event (use existing "activation behavior" concept):

Listen to mousedown/keydown event on select and mouseup/keydown on options:

  • Does not break action vs occurrence
  • Specifically on the select element, it matches existing appearance:auto behavior which I'd prefer not to try changing
  • Enables the click and drag user interaction if we choose this for both the select element and option element.

Am I representing everyone's thoughts well with this? Does anyone have strong preferences for one of these two options? Should we split them by doing something like mousedown for the select element and click for the option element?

Note: If we want to document the action of using the arrow keys to move focus between the options, then we will still need to have something that lives outside the "activation behavior" concept, but maybe that's OK because I wouldn't call that "activating" the option element.

@josepharhar josepharhar added the agenda+ To be discussed at a triage meeting label Dec 10, 2024
@chrishtr
Copy link
Contributor

Idea: would it be possible to listen for both mouse down/up and click, and have the first to happen do the default browser action? That way we'd allow the developer to call click and have it do things, and it wouldn't activate twice on a user mouse click. (Not sure if this is a bad idea or not, just asking.)

@Permik
Copy link

Permik commented Dec 10, 2024

I don't think there's actually a need to do a split on the activation part of the spec as select is not a button, so clicking on it is not semantically an action, but a focus event.

Fwiw mousedown action for a select element is a case of focusing, not actually activation of the element yet. But after that selecting an option via either clicking or continuing the ongoing drag click operation will bubble up the activation event to the select element I guess?

This explanation seems to be semantically sound without doing any inherent changes to the spec.

@dbaron
Copy link
Member

dbaron commented Dec 10, 2024

One other factor is that developers sometimes prefer keydown/mousedown simply because it happens sooner, and thus makes the UI feel faster and more responsive.

(I also have a bit of a bias because I'm a reasonably frequent user of the drag-to-select UI in dropdown selects, which depends on the select opening on mousedown, and on option selection happening with the corresponding mouseup on an option.)

@josepharhar
Copy link
Contributor Author

We discussed this at WHATNOT:

  • click-and-drag is an important user interaction that is supported across all desktop browsers.
  • Due to the priority of constituencies, we should prioritize the user interaction over spec purity or making things easier for developers.
  • Also we should add user-select:none to the UA stylesheet to make sure that the click and drag use case doesn't start a selection.

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Dec 13, 2024
mouseup is better than mousedown because it allows the user to click and
drag to choose an option like appearance:auto already does. More
justification here:
whatwg/html#10762 (comment)

Change-Id: Ifa63d497b7dcfbc3d07e19d6a7850bddf57f78fc
aarongable pushed a commit to chromium/chromium that referenced this issue Dec 13, 2024
mouseup is better than mousedown because it allows the user to click and
drag to choose an option like appearance:auto already does. More
justification here:
whatwg/html#10762 (comment)

Change-Id: Ifa63d497b7dcfbc3d07e19d6a7850bddf57f78fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6077672
Commit-Queue: Joey Arhar <[email protected]>
Reviewed-by: Traian Captan <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1396126}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Dec 13, 2024
mouseup is better than mousedown because it allows the user to click and
drag to choose an option like appearance:auto already does. More
justification here:
whatwg/html#10762 (comment)

Change-Id: Ifa63d497b7dcfbc3d07e19d6a7850bddf57f78fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6077672
Commit-Queue: Joey Arhar <[email protected]>
Reviewed-by: Traian Captan <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1396126}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Dec 13, 2024
mouseup is better than mousedown because it allows the user to click and
drag to choose an option like appearance:auto already does. More
justification here:
whatwg/html#10762 (comment)

Change-Id: Ifa63d497b7dcfbc3d07e19d6a7850bddf57f78fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6077672
Commit-Queue: Joey Arhar <[email protected]>
Reviewed-by: Traian Captan <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1396126}
@past past removed the agenda+ To be discussed at a triage meeting label Dec 18, 2024
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Dec 18, 2024
…to mouseup, a=testonly

Automatic update from web-platform-tests
Make customizable select options listen to mouseup

mouseup is better than mousedown because it allows the user to click and
drag to choose an option like appearance:auto already does. More
justification here:
whatwg/html#10762 (comment)

Change-Id: Ifa63d497b7dcfbc3d07e19d6a7850bddf57f78fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6077672
Commit-Queue: Joey Arhar <[email protected]>
Reviewed-by: Traian Captan <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1396126}

--

wpt-commits: 0c1d19546fd4873bb9f4147f0bbf868e7b4f91b7
wpt-pr: 49684
ErichDonGubler pushed a commit to erichdongubler-mozilla/firefox that referenced this issue Dec 19, 2024
…to mouseup, a=testonly

Automatic update from web-platform-tests
Make customizable select options listen to mouseup

mouseup is better than mousedown because it allows the user to click and
drag to choose an option like appearance:auto already does. More
justification here:
whatwg/html#10762 (comment)

Change-Id: Ifa63d497b7dcfbc3d07e19d6a7850bddf57f78fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6077672
Commit-Queue: Joey Arhar <[email protected]>
Reviewed-by: Traian Captan <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1396126}

--

wpt-commits: 0c1d19546fd4873bb9f4147f0bbf868e7b4f91b7
wpt-pr: 49684
@josepharhar
Copy link
Contributor Author

I implemented the mouseup behavior, but it broke demos which position the picker on top of the button: https://issues.chromium.org/issues/385300320

This is a common use case and is how the MacOS select picker works. The only solution I can think of so far is to prevent mouseup from choosing the option until mouseleave has been fired within any of the options, and also to add a click event listener to make the case where the user clicks on the option that shows up under the cursor when opening the picker still works.

This is kind of ugly since it adds state and two different ways to choose an option. If anyone has better ideas, I'd love to hear them.

gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Jan 1, 2025
…to mouseup, a=testonly

Automatic update from web-platform-tests
Make customizable select options listen to mouseup

mouseup is better than mousedown because it allows the user to click and
drag to choose an option like appearance:auto already does. More
justification here:
whatwg/html#10762 (comment)

Change-Id: Ifa63d497b7dcfbc3d07e19d6a7850bddf57f78fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6077672
Commit-Queue: Joey Arhar <jarharchromium.org>
Reviewed-by: Traian Captan <tcaptanchromium.org>
Cr-Commit-Position: refs/heads/main{#1396126}

--

wpt-commits: 0c1d19546fd4873bb9f4147f0bbf868e7b4f91b7
wpt-pr: 49684

UltraBlame original commit: 67679d9657af23ee3aa91fe6adc71e254e62fa41
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Jan 1, 2025
…to mouseup, a=testonly

Automatic update from web-platform-tests
Make customizable select options listen to mouseup

mouseup is better than mousedown because it allows the user to click and
drag to choose an option like appearance:auto already does. More
justification here:
whatwg/html#10762 (comment)

Change-Id: Ifa63d497b7dcfbc3d07e19d6a7850bddf57f78fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6077672
Commit-Queue: Joey Arhar <jarharchromium.org>
Reviewed-by: Traian Captan <tcaptanchromium.org>
Cr-Commit-Position: refs/heads/main{#1396126}

--

wpt-commits: 0c1d19546fd4873bb9f4147f0bbf868e7b4f91b7
wpt-pr: 49684

UltraBlame original commit: 67679d9657af23ee3aa91fe6adc71e254e62fa41
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Jan 1, 2025
…to mouseup, a=testonly

Automatic update from web-platform-tests
Make customizable select options listen to mouseup

mouseup is better than mousedown because it allows the user to click and
drag to choose an option like appearance:auto already does. More
justification here:
whatwg/html#10762 (comment)

Change-Id: Ifa63d497b7dcfbc3d07e19d6a7850bddf57f78fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6077672
Commit-Queue: Joey Arhar <jarharchromium.org>
Reviewed-by: Traian Captan <tcaptanchromium.org>
Cr-Commit-Position: refs/heads/main{#1396126}

--

wpt-commits: 0c1d19546fd4873bb9f4147f0bbf868e7b4f91b7
wpt-pr: 49684

UltraBlame original commit: 67679d9657af23ee3aa91fe6adc71e254e62fa41
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this issue Jan 2, 2025
…to mouseup, a=testonly

Automatic update from web-platform-tests
Make customizable select options listen to mouseup

mouseup is better than mousedown because it allows the user to click and
drag to choose an option like appearance:auto already does. More
justification here:
whatwg/html#10762 (comment)

Change-Id: Ifa63d497b7dcfbc3d07e19d6a7850bddf57f78fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6077672
Commit-Queue: Joey Arhar <[email protected]>
Reviewed-by: Traian Captan <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1396126}

--

wpt-commits: 0c1d19546fd4873bb9f4147f0bbf868e7b4f91b7
wpt-pr: 49684
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: select The <select> element
Development

No branches or pull requests

8 participants