Monday, 8 February, 2021 UTC


Summary

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.