In this tutorial, we’ll take a deep-dive into the little-used HTML5 <datalist>
element. It can implement a lightweight, accessible, cross-browser autocomplete form control that doesn’t require JavaScript.
What’s Wrong with
<select>
?
HTML5 <select>
controls are ideal when you want the user to choose from a small range of options. They’re less practical when:
- there are lots of options, such as countries or job titles
- the user wants to enter their own option which is not on the list
The obvious solution is an autocomplete control. This allows the user to enter a few characters, which limits the options available for quicker selection.
<select>
will jump to the right location as you start typing, but that’s not always obvious. It won’t work on all devices (such as touchscreens), and it resets within a second or two.
Developers often turn to one of the many JavaScript-powered solutions, but a custom autocomplete control is not always necessary. The HTML5 <datalist>
element is lightweight, accessible, and has no JavaScript dependencies. You may have heard it’s buggy or lacks support. That’s not true in 2021, but there are browser inconsistencies and caveats.
<datalist>
Quick Start
Picking your country from a list containing more than 200 options is an ideal candidate for an autocomplete control. Define a <datalist>
with child <option>
elements for every country directly in an HTML page:
<datalist id="countrydata">
<option>Afghanistan</option>
<option>Åland Islands</option>
<option>Albania</option>
<option>Algeria</option>
<option>American Samoa</option>
<option>Andorra</option>
<option>Angola</option>
<option>Anguilla</option>
<option>Antarctica</option>
...etc...
</datalist>
The datalist’s id
can then be referenced by a list
attribute in any <input>
field:
<label for="country">country</label>
<input type="text"
list="countrydata"
id="country" name="country"
size="50"
autocomplete="off" />
Confusingly, it’s best to set autocomplete="off"
. This ensures the user is shown values in the <datalist>
but not values they previously entered in the browser.
The result:
This is the default rendering in Microsoft Edge. Other applications implement similar functionality, but the look differs across platforms and browsers.
<option>
Options
Using the label as a text child of an <option>
is common:
<datalist id="mylist">
<option>label one</option>
<option>label two</option>
<option>label three</option>
</datalist>
Using a value
attribute produces identical results:
<datalist id="mylist">
<option value="label one" />
<option value="label two" />
<option value="label three" />
</datalist>
Note: the closing />
slash is optional in HTML5, although it could help prevent coding errors.
You can also set a value according to a chosen label using either of the following formats.
Option 1:
<datalist id="mylist">
<option value="1">label one</option>
<option value="2">label two</option>
<option value="3">label three</option>
</datalist>
Option 2:
<datalist id="mylist">
<option value="1" label="label one" />
<option value="2" label="label two" />
<option value="3" label="label three" />
</datalist>
In both cases, the input field is set to 1
, 2
or 3
when a valid option is chosen, but the UI varies across browsers:
- Chrome shows a list with both the value and the label. Only the value remains once an option is chosen.
- Firefox shows a list with the label only. It switches to the value once an option is chosen.
- Edge shows the value only.
The following CodePen example shows all variations:
See the Pen
HTML5 <datalist> autocomplete examples by SitePoint (@SitePoint)
on CodePen.
Implementations will evolve but, for now, I’d advise you do not use a value and label since it’s likely to confuse users. (A workaround is discussed below.)
<datalist>
Browser Support and Fallbacks
The <datalist>
element is well supported in modern browsers as well as Internet Explorer 10 and 11:
There are several implementation notes, but they won’t affect most usage. The worst that could happen is a field reverts to a standard text input.
If you absolutely must support IE9 and below, there’s a fallback pattern which uses a standard <select>
in conjunction with a text input when the <datalist>
fails. Adapting the country example:
<label for="country">country</label>
<datalist id="countrydata">
<select name="countryselect">
<option></option>
<option>Afghanistan</option>
<option>Åland Islands</option>
<option>Albania</option>
<option>Algeria</option>
<option>American Samoa</option>
<option>Andorra</option>
<option>Angola</option>
<option>Anguilla</option>
<option>Antarctica</option>
...etc...
</select>
<label for="country">or other</label>
</datalist>
<input type="text"
id="country" name="country"
size="50"
list="countrydata"
autocomplete="off" />
See the Pen
HTML5 <datalist> autocomplete fallback by SitePoint (@SitePoint)
on CodePen.
In modern browsers, the <option>
elements become part of the <datalist>
and the “or other” label is not shown. It looks identical to the example above, but a countryselect
form value will be set to an empty string.
In IE9 and below, both the (very long) <select>
and text input fields are active:
Both values could be entered in old IEs. Your application must either:
- decide which is most valid, or
- use a small JavaScript function to reset one when the other is changed
Continue reading
Lightweight Autocomplete Controls with the HTML5 Datalist
on SitePoint.