open-ui
open-ui copied to clipboard
How to make an accessible searchable "select" list?
I was reading this article on gregs website: https://www.gwhitworth.com/posts/2019/can-we-please-style-select/
This article points out why we need <selectlist>, but also says that the top frustration with <select> is "Not being able to create a good user experience for searching within the list." There is an example in the demos which adds a text input in the listbox to filter which addresses this top frustration, but based on what I've been hearing from accessibility experts, there should not be any interactive content inside the listbox element except for <option>s.
So my question for accessibility people is: what is the right pattern to create a select-like thing where you can filter the options? Is that just called a combobox, where instead of a button to open the listbox there is a text field?
I see in this combobox in aria practices that the user can still sort of commit any text they want even if its not a valid option... what if you want to limit the possible choices to whats in the listbox like the one in the demos?
@scottaohara
there should not be any interactive content inside the listbox element except for <option>s
I think that this is only with the listbox role, but with the <listbox> element, the accessibility API mappings and content model could be different, to allow for this.
where instead of a button to open the listbox there is a text field?
I feel that we shouldn't allow for the search input to replace the selectlist's button element.
Since then authors could use this element as more of a text autocomplete, than a <select> element.
But this then raises the question of how dynamic data would work. Since usually text autocompletes have loads of options which users can choose from, for example, a search engine's search bar. Where it'd be unpractical to have all these <option> elements.
The ability to search through the options would best work where data is static. For example, searching through countries to choose a location.
I made this issue in ARIA due to the fact I see people trying to do this sort of thing a lot - https://github.com/w3c/aria/issues/2051 - creating a combobox to open a listbox that essentially has a combobox with an open listbox within in it... it's a bit inception, but i can also see why people do it.
I see in this combobox in aria practices that the user can still sort of commit any text they want even if its not a valid option... what if you want to limit the possible choices to whats in the listbox like the one in the demos?
well, they can 'commit' any sort of text with that just because it's a demo, really. Additional validation/error prevention could be put in place.
anyway, Brecht created a filterable like this the other day that I forked to make the markup adhere to how someone would be instructed to do this now (re: it currently being invalid to put a searchbox inside of a listbox).
I've commented the heck out of that, so i'm not going to repeat it here (and there are still some accessibility gaps per the back and forth we've been having on gaps/questions with selectlist - i mentioned this exact situation in that list as well, but we haven't discussed it yet)
I think that this is only with the listbox role, but with the
<listbox>element, the accessibility API mappings and content model could be different,
eh? sort of? the "right way" to do this would be to adjust the allowed content of a listbox role (see ARIA issue i opened), not to have a listbox element that had an amorphous listbox role mapping. Though that might have to be the reality here per the mantra of allowing whatever the heck inside of the listbox part. But it'd just be better to account for things that authors are highly likely to do, and then wonder what the hell is going on with those that put an iframe or a video inside of the listbox.
We desperately need a Selectlist with a search, for example in very common scenarios such as language or country selection, where the search helps the user to quickly find the desired item.
There is an experimental flag (dom.forms.selectSearch) in Firefox.
https://www.deepl.com/en/translator
Also, serach value need to be accesible to js for server side filtering for example
There is also an example here under "Search Selection" where the button contains the search: https://semantic-ui.com/modules/dropdown.html . This is a common UI pattern and something to consider RE: interaction between selectedoption and the button
that firefox experiment is really interesting (and really an experiment! can't seem to figure out how to get to it with keyboard alone at all / force putting focus into it with mouse and JAWS turned on doesn't do much in the way of announcing anything, right now. but i assume that's all still being worked on, hence, experimental feature).
but yeh, how that'd need to be built on the web (re: present allowances) covered in the demo i mentioned in my previous post
For fear of stating the obvious, is it not possible to enhance/build upon <datalist> to achieve the same effect?
maybe? browsers would have to not only agree to allow styling of the datalist popup, but also change their current parsing behavior of stripping out any non-text content from the rendered options (e.g., images just go away. and any other markup within the option just gets flattened into a text string, which then is what is shown in the options of the popup). that second bit, from my understanding, would be the major blocker for using datalist, as changing that could potentially break current invalid, but at least properly rendering due to the browser behavior, datalist options.
Potentially could allow a listbox inside datalist element and that would enable the new stylability?
I do feel like there's a case for stylable datalists alongside any solution for searchable selectlist (even if they're not the same solution in the end)
Potentially could allow a listbox inside datalist element and that would enable the new stylability?
so a listbox inside of a listbox (a datalist is already mapped to be a listbox)? sounds like we should just use the listbox then and build in support that the list attribute can be used to point to the ID of a datalist or a listbox element.
Uhhh yeah that, that makes a lot more sense 😅😂.
There hasn't been any discussion on this issue for a while, so we're marking it as stale. If you choose to kick off the discussion again, we'll remove the 'stale' label.
Hopefully this use case can be tackled by <combobox> or an interoperable/stylable version of <input type=text> + <datalist>
Hopefully this use case can be tackled by
<combobox>or an interoperable/stylable version of<input type=text>+<datalist>
Grouping is a use case we have found where modeling as a select with filtering vs a combobox text input with autocomplete is significantly different.
i.e:
pick a city:
Texas
- Paris
France
- Paris
Modeled as a select can distinguish the group (Texas vs France). Modeled as text input have to invent strange encodings / workarounds (encoding the group as part of the value, which you probably don't want users to have to see / mess with) to distinguish groups.
I hope this issue is considered as part of the customizable select work.
There hasn't been any discussion on this issue for a while, so we're marking it as stale. If you choose to kick off the discussion again, we'll remove the 'stale' label.
Removing stale as this is definitely something we still need to come up with a solution for. Even if it's an updated codepen that demonstrates how you could go about doing this using the shipping customisable select.
At face value updating the codepen above: https://codepen.io/lukewarlow/pen/xbxxjrz seems to "work" (Ignore some styling bugs I was lazy)
a lot of the aria in that demo can likely be ripped out now. not all of it, but a lot of it is either redundant and/or ignored now with the a11y mappings having been implemented (all? mostly? need to double check, but was under the impression it had been).
i'll try to carve out some time to trim this down
Yeah the dialog role bit at least I think is redundant unless we need it on that element for one of the other elements to link to?
Customizable select should make it possible to put an <input> inside the picker, but making the button itself become a text input is probably no longer possible since we made the author provided button inert.
Putting an <input> inside the picker will probably also require script due to existing sites being unwilling to migrate off the legacy parser behavior of making <input> tags add a </select> when used inside a <select>.
Given you'll need script for the search functionality itself (at least initially) it's not to bad if you need it to insert the input. Shame if the parser can't allow it though.
Given https://github.com/whatwg/html/issues/11288 it'd be good to get some sort of story around this. Even if it's "you can't do this yet", given previous discussions it would seem that it's at least close to doable given what we have. (Might need some parser tomfoolery for the input but I think per recent HTML discussions we can wrap it in any element like a div and it'll parse)
We should probably make the filtering work automatically without making authors implement their own script to filter options.
For putting a text filter inside the select element's popup, here are some options that I think we have:
- Require the author to put an
<input>inside the picker- We have to hope that the author puts the
<input>before the<option>s. Is there any legitimate case for doing otherwise? - This also requires tracking which
<input>is the first, whether it comes before<option>s or not, just additional bookkeeping to do in the browser which isn't ideal but is doable. - Should an attribute be set on the input element to say that its being used as a filter? Or should that be done automatically?
- Should
<input type=search>and<input type=text>be supported? - Requires more parser changes to allow
<input>in<select>, which will likely require wrapping it with a<div>or some other unintuitive thing.
- We have to hope that the author puts the
- Add an HTML or CSS opt-in to display a filter input automatically
- We could add an
<input>to the UA shadowroot at the beginning of the picker before the slot element for the options and other nodes. - Strengthens guarantees that it comes before options and that it's easy for the browser to track it in the DOM.
- This could be targeted with a part-like pseudo-element, like
select::text-filter. - How would we get the current value of the text input from script? Expose a new script IDL on the select element? Is this even needed?
- We could add an
- Variation on option 2, but only show the text input when the browser thinks there are too many options.
- I think this is how the firefox experiment works.
- Could make it not needed to opt in via html or css, but not sure if this would be liked by authors.
Authors will want the ability to control how search works (startsWith or contains for example). They'll also want the ability to react to changes in the value via script for server side filtering.
Perhaps we can provide a built in ability but have a way for authors to provide their own input element (needing to wrap it in another element seems fine?).
my vote would be that the input, regardless of where it is placed, becomes the first element of its closest parent group/listbox element, after any legend that might exist.
the most common reason to have an input in a popup like this is because you want to filter/search the available options.
so:
<select>
...
<option>foo</option>
<input value="i'm second cause lol expectations">
<option>bar</option>
</select>
would have the popup render as input, foo, bar
where as
<select>
...
<option>foo</option>
<optgroup>
<legend>sub-group</legend>
<option>bar</option>
<input>
<option>baz
</optgroup>
</select>
would render in the order of: foo, sub-group, input, bar, baz
there can be a user case where someone wants to add a text field to create new options - but we're getting well into the territory of a more customized component that will need additional scripting and likely other controls like add/remove buttons. that's not going to be what the majority of web authors will need.