Under-Engineered Comboboxen?
When I wrote Under-Engineered Text Boxen in 2019 I mentioned <datalist>
(WHATWG, MDN) but did not dwell on it. Partly because support was poor at the time.
Once Can I Use’s <datalist>
entry listed Firefox on Android supporting it in version 110, I got excited and started testing to write this post. Then I opened Firefox on Android and stopped writing this post. I have only come back to it reluctantly.
Unlike all my other Under-Engineered posts, this one is not a “how-to”. This is a “what’s-up”, so you can make a decision about whether or not you want to give <datalist>
a shot.
TL;DR
If you want a native HTML combobox, look no further than <datalist>
.
Unless…
- It needs to work as more than a text box in Firefox on Android;
- Options need to be available in landscape mode in Chrome on Android;
- Users ever need to zoom the text;
- Voice control is a requirement for your users;
- It is imperative you can style the options; and/or
- The
value
will differ from the node text / innertext in your code.
If any of those is a deal breaker, then probably move along. The first four are deal-breakers for me, the last two are items over which I can exert control.
Styling
The good news is the styling guidance from Under-Engineered Text Boxen is still valid. The bad news is that it has no effect on the <datalist>
itself.
This block of code styles the text field (as explained in the original post) but I have extended it to include <datalist>
and <option>
:
textarea,
input,
datalist,
datalist > option {
font: inherit;
letter-spacing: inherit;
word-spacing: inherit;
}
That results in this example (cruft-free version) with plain text fields for comparison:
See the Pen Under-Engineered Text Boxen, Simple by Adrian Roselli (@aardrian) on CodePen.
Visual Cues
As a sighted user you may want visual cues that a text field has a datalist. So I collected the differences, some of which you can see in the screen shots following this section.
Only Safari shows a visual cue prior to interaction (an arrow). Chrome and Edge first show it on hover (of the associated <label>
as well). Firefox never shows an arrow, but it does show the datalist on a second click or on input.
Firefox 114 (current release as of this writing) on Android (there is no Firefox engine on iOS, so “mobile” means Android) has a problem. Despite Can I Use’s <datalist>
entry claiming Firefox on Android supports it as of version 110, this does not appear to be the case (bugs linked at end of post while awaiting my PR to make it to the site). No list of options appears and the values are not used as autocomplete hints.
I leave it to you to decide if that is a deal breaker for you.
Testing minutiae
- Chrome 114
- At rest: nothing
- On hover: displays arrow
- On keyboard focus (desktop): displays arrow and options
- On click focus: displays arrow and options
- On tap focus: displays arrow and options
- On tap focus (mobile): displays arrow and options (above keyboard)
- On input: displays arrow and options, filtering the list
- On input (mobile): displays arrow and options, filtering the list (above keyboard)
- Firefox 114
- At rest: nothing
- On hover: nothing
- On keyboard focus (desktop): nothing
- On click focus: nothing
- On focus then click: displays options
- On tap focus (mobile): nothing
- On input: displays filtered options
- On input (mobile): nothing
- Safari 16.5
- At rest: displays arrow
- On hover: displays arrow
- On keyboard focus (desktop): displays arrow
- On click focus: displays arrow and options
- On tap focus (mobile): displays arrow and options (above keyboard)
- On input: displays arrow and options, filtering the list
- On input (mobile): displays arrow and options, filtering the list (above keyboard)
- Edge 114
- At rest: nothing
- On hover: displays arrow
- On keyboard focus (desktop): displays arrow and options
- On click focus (desktop): displays arrow and options
- On tap focus (desktop): displays arrow and options
- On input (desktop): displays arrow and options, filtering the list
<option>
Text versus value
My datalist has four variations of <option>
s:
- an
<option>
with novalue
, - a
value
that does not match the text node (display text if this was a<select>
), - a
value
that does, and - no display text (only
value
).
<datalist id="berrylist"> <option>Blackberry</option> <option value="Blueberry">#00Fberry</option> <option value="Boysenberry">Boysenberry</option> <option value="Chuckberry"> […]
You may be used to <select>
menus where the value
and text can differ without it affecting the display. If, however, you continue that practice — or re-use your <option>
lists between these kinds of controls in an effort to follow DRY principles — then this can be a bit of a big deal.
I’ll let the screen shots speak for themselves.
Firefox on Windows is the only browser to treat the text node as you might expect from using <select>
, showing it while hiding the value
(10-year old Firefox bug to show both). The safest takeaway here for all browsers might be to ensure your value
and text match or you exclude one of them completely.
Accessible Name/Value
You might (should) wonder how that affects the accessible name or value. Using Microsoft Accessibility Insights for Windows, I inspected each to see how they were exposed. I did not do the same on macOS, Android, nor iPadOS. The accessibility inspectors of each browser balked at giving me the information I wanted and I opted to take a nap instead.
The only surprise from the four options I noted above would be this one:
<option value="Blueberry">#00Fberry</option>
- Firefox
- #00fberry
- Chrome
- blueberry #00fberry
- Edge
- blueberry, #00fberry
I separated Edge from Chrome because Edge uses UI Automation (UIA) and Chrome uses an IA2 (IAccessible2) to UIA proxy. I thought the addition of the comma from Edge was quaint.
Screen Reader
VoiceOver on macOS announces only the value
when it differs from the node text, meaning it does not announce all visible text for an option. Firefox on Android does not support datalist, so no surprise TalkBack can do nothing with it. Otherwise, datalist generally works fine with screen readers.
Screen reader notes
I did not record videos. They take so darn long. So here is my rambly explanation of each platform.
JAWS (with Chrome) refers to the field as a combo
and then lets you know an Autofill List box expanded
. As you navigate the items, it provides a count and reads all the visible text (value
and text node if provided). After you pick a value and return to the field, JAWS does not announce the value. You have to arrow through the field or go into the list (if your value is in there and in there only once).
NVDA (with Firefox) also refers to the field as combo box, has auto complete
, which is a prompt to hit the down arrow and expand the options. Unlike JAWS, NVDA announces the value in the field when you return to the field.
Narrator (with Edge) says combo edit has popup, suggestions available
. If you switch scan mode on you can arrow into the choices where it provides a count and position within that count. It will also announce all visible text (value
and text node if provided).
VoiceOver (Safari on macOS) announces as list box pop up, edit text
. Only when you start typing a value does VoiceOver announce suggestions list visible
, though it never made it through the entire statement before echoing back what I typed. Then it announces Safari has new window
which, sure. I can then arrow through options. Also of note is that VoiceOver does not announce all visible text, announcing only the value
when it differed from the text node.
TalkBack (Chrome) tells you it’s a datalist but gives no insight into what will happen beyond instructions to edit. Once you do, it says autofill suggestions above the keyboard
. As you navigate to the options (see my bug report in the Keyboard section below), the total count is announced one greater because it considers the Android keyboard passwords button to be part of the count.
Firefox does not work with datalists, so I am excluding its interaction with TalkBack.
VoiceOver (Safari on iPadOS) announces as list box pop up, double-tap to edit
. No options are visible until you start typing, and only the first three appear above the keyboard. You can swipe to them (or use explore-by-touch), but you will not get a count and cannot swipe through to more than what is displayed.
Keyboard
Keyboard support is generally good. Safari does not dismiss on Esc and you must start typing to see the options. I am excluding Firefox on Android given its lack of overall support.
Chrome on Android’s current method of displaying these options to users has two significant drawbacks:
- The only way for a TalkBack user to access them is by using explore-by-touch or navigating to the very end of the page (well past the field), and
- They disappear in landscape mode.
This maps very closely to an issue I filed in April 2023, Issue 1439681: Autocomplete ribbon is lost in landscape view. The additional options announce the same (autofill suggestions available above the keyboard
) and the behavior is the same, so I am going to re-use the video I created for that bug (I spent a lot of time on it, after all):
The landscape keyboard issue could be a deal breaker in some cases, but if you chose this control then that means you are not requiring the user to enter exact matches for existing options.
Voice Control
I have a slightly more human-pronounceable option for this test:
<option value="Huckleberry, I’ll be your">Not a berry</option>
Overall, voice control support is not ideal. I got nowhere on macOS and iPadOS, but had good luck with Chrome and Edge on Windows and Chrome on Android. Firefox did not play at all. Granted, much of this may be moot if your bespoke ARIA combobox also performs similarly to what I recorded here.
Voice control narrative
With Windows Voice Access and Chrome or Edge, I can speak either visible text (“Not” or “Huckleberry”) and it will select the option I want. Firefox declined to support any commands that were not system level (setting grids, but showing numbers would not set numbers in the viewport) which, along with other tests, leads me to believe Voice Access does not work with Firefox.
On macOS using Voice Control I was unable to choose an option from the list. It would not expand when I put focus on the field, so I had to trigger it by inputting letters or words. When I did get the list, switching to command mode and telling it to click on anything got me nowhere. Operating a native <select>
, by comparison, was easy with Voice Control.
Voice Access on Android worked fine with Chrome, allowing me to select either the value
or text node. Since Firefox seems to treat this as a plain text field, there was nothing to test there (though I could select and edit the field).
I had no luck with Voice Access on iPadOS. I could not get the list of options to expand with just my voice, and they did not appear above the keyboard until I started typing. I noted that every control on the screen had a voice hint except the options, suggesting I might never be able to select one.
Zoom
No desktop browser scales the options when you scale the page.
This would not fail SC 1.4.4:Resize Text (Level AA) because the text is controlled by the user agent (which means the browsers all fail UAAG 1.0 Checkpoint 4.1, for what little they care).
Changing the default text size in the browser settings (or with Option + ⌘ + + in Safari) has no effect either. Doubling it gives the same screen shots as above.
Because these controls are rendered from the browser, it should be familiar from one of my arguments against using default field validation (the lack of zoom support) and the outcomes of these three bugs may affect it:
- Mozilla: 1756203: Users need a way to increase the size of overlays/menus that come from web content but are styled as browser UI (e.g. datetime-picker, text-input datalist, alert(), prompt(), tooltip), 18 February 2022
- Chromium: 1322462: The form control error message doesn’t zoom while zooming in on the page (CMD +/- on MacOS), 4 May 2022
- WebKit: 240077: AX: Default field validation messages do not zoom with page, 4 May 2022
Windows High Contrast Mode
Or Windows Contrast Themes, or CSS forced-colors mode, or just calling system colors, or whatever you call it (my explainer for all that). Either way, Chrome and Edge have no problem styling the datalist with the appropriate system colors. Firefox chooses not to.
Testing Suite
This post is current for as long as this list is current.
- Windows 11 22621.1702
- Assistive technology
- JAWS 2023.2306.38
- NVDA 2023.1
- Narrator
- Voice Access
- Contrast Themes (High Contrast Mode)
- Chrome 114
- Firefox 114
- Edge 114
- Assistive technology
- macOS 12.6.6
- Assistive technology
- VoiceOver
- Voice Control
- Safari 16.5
- Assistive technology
- Android 13
- Assistive technology
- TalkBack 13.1
- Voice Access
- Chrome 114
- Firefox 113–114
- Assistive technology
- iPadOS 16.5
- Assistive technology
- VoiceOver
- Voice Control
- Safari 16.5
- Assistive technology
Wrap-up
I have wanted to use this element for years. I think in the right context and with the right audience you can. I am still holding off, however.
While I was mulling this post over, Dennis Lembrée published Datalist over ARIA combobox.
I also filed one bug, found two more, and filed a PR:
- Firefox: 1840724: Neither <datalist> nor its <option>s are exposed in Firefox for Android, 27 June 2023 and closed as a duplicate (because my Bugzilla search skills are pants).
- Confirmation
<datalist>
was not supported in Firefox 104 and 105: 1783594: Input with <datalist> elements don’t autocomplete, 7 August 2022 and also closed as duplicate. - Firefox bug 1535985: <datalist> HTML element should display autocompletion drop-down UI, 17 March 2019 and still open.
- Can I Use PR 6769 Update datalist.json for Firefox/Android support, 28 June 2023, merged 29 June 2023.
- JAWS bug 784 Value of an HTML combo box (datalist) is not output by JAWS (Edge, Chrome) (noted in the screen reader section above), filed 20 November 2023.
Update: 30 September 2024
I am thrilled Apple has rolled out some needed fixes for the <datalist>
element, as spotted by Jeremy Keith and reported in his post The datalist element on iOS. He has also identified other odd behaviors that probably warrant filing a bug.
I suspect some of these updates came because <datalist>
was originally planned to be the containing element for customizable <select>
s (now that <selectmenu>
is dead) as proposed by Open UI.
Unfortunately, this still does not mean you can use <datalist>
in production and expect full support. The bugs I identified above in Firefox and JAWS are still open.
3 Comments
This is an excellent piece of research, presented brilliantly. Thank you.
Man, this is a great piece of code. thank you very much for sharing.
Am I the only one who finds datalist unusable? Pick an option from the dropdown, and then return to the dropdown to change to a different option… hmmm… where did my options go?
Please don’t use datalist unless you actually want to torture your users.
Leave a Comment or Response