The design of datalist

One of the many form enhancements provided by HTML5 is the datalist element. It allows you to turn a regular input field into a .

Using the list attribute on an input, you can connect it to a datalist with the corresponding ID. The datalist itself contains a series of option elements.

<input list="suggestions">
<datalist id="suggestions">
    <option value="foo"></option>
    <option value="bar"></option>
    <option value="baz"></option>
</datalist>

I can imagine a number of use cases for this:

  • “Share this” forms, like the one on Last.fm, that allow you to either select from your contacts on the site, or enter email addresses, separated by commas. Using input type="email" with a multiple attribute, in combination with a datalist would work nicely.
  • Entering the details for an event, where you can either select from a list of venues or, if the venue is not listed, create a new one.
  • Just about any form that has a selection of choices, of which the last choice is “other”, followed by “If other, please specify…”

You can take something like this:

<label for="source">How did you hear about us?</label>
<select name="source">
    <option>please choose...</option>
    <option value="television">Television</option>
    <option value="radio">Radio</option>
    <option value="newspaper">Newspaper</option>
    <option>Other</option>
</select>
If other, please specify:
<input id="source" name="source">

And replace it with this:

<label for="source">How did you hear about us?</label>
<datalist id="sources">
    <option value="television"></option>
    <option value="radio"></option>
    <option value="newspaper"></option>
</datalist>
<input id="source" name="source" list="sources">

The datalist element has been designed according to one of the design principles driving HTML5—Degrade Gracefully:

On the World Wide Web, authors are often reluctant to use new language features that cause problems in older user agents, or that do not provide some sort of graceful fallback. HTML 5 document conformance requirements should be designed so that Web content can degrade gracefully in older or less capable user agents, even when making use of new elements, attributes, APIs and content models.

Because the datalist element contains a series of option elements with value attributes, it is effectively invisible to user-agents that don’t support the datalist element. That means you can use the datalist element without worrying it “breaking” in older browsers.

If you wanted, you could include a message for non-supporting browsers:

<datalist id="sources">
    Your browser doesn't support datalist!
    <option value="television"></option>
    <option value="radio"></option>
    <option value="newspaper"></option>
</datalist>

That message—“Your browser doesn’t support datalist!”—will be visible in older browsers, but browsers that support datalist know not to show anything that’s not an option. But displaying a message like this for older browsers is fairly pointless; I certainly wouldn’t consider it graceful degradation.

In my opinion, one of the best aspects of the design of the datalist element is that you can continue to do things the old-fashioned way—using a select and an input—and at the same time start using datalist. There’s no violation of either; you can use the same option elements for the select and the datalist:

<label for="source">How did you hear about us?</label>
<datalist id="sources">
    <select name="source">
        <option>please choose...</option>
        <option value="television">Television</option>
        <option value="radio">Radio</option>
        <option value="newspaper">Newspaper</option>
        <option>Other</option>
    </select>
    If other, please specify:
</datalist>
<input id="source" name="source" list="sources">

Browsers that support datalist will display the label “How did you hear about us?” followed by a combo-box text field that allows the user to select an option, or enter some free text.

Browsers that don’t support datalist will display the the label “How did you hear about us?” followed by a drop-down list of of options (the last of which is “other”), followed by the text “If other, please specifiy”, followed by a text field.

Take a look at this example in Opera to see datalist in operation. Take a look at it in any other browser to see the fallback. The source is on Github if you’d like to play around with it.

WebKit’s mistake

If you try that example in any browser, you’ll get something that works; either through datalist support or through the select fallback …unless the browser is using WebKit.

It took me a while to figure out why this would be the case. I didn’t think that Safari or Chrome supported datalist and a little digging around with object detection in JavaScript confirmed this. So why don’t those browsers follow the standard behaviour and simply ignore the element they don’t understand and render what’s inside it instead.

Here’s the problem: line 539 of WebKit’s default CSS:

datalist {
    display: none;
}

This is pretty much the worst possible behaviour for a browser to implement. An element should either be recognised—like p, h1 or img—and parsed accordingly, or an element is unrecognised—like foo or bar—and ignored. WebKit does not support the datalist element (even in the current nightly build), so the element should be ignored.

Fortunately the problem is easily rectified by adding something like this to your own stylesheet:

datalist {
    display: inline-block;
}

I’ve submitted a bug report on the WebKit Bugzilla.

Update: That Webkit bug has now been fixed so the extra CSS is no longer necessary.

Have you published a response to this? :

Responses

adactio.com

One of the many form enhancements provided by HTML5 is the datalist element. It allows you to turn a regular input field into a .

Using the list attribute on an input, you can connect it to a datalist with the corresponding ID. The datalist itself contains a series of option elements.

<input list="suggestions">
<datalist id="suggestions"> <option value="foo"></option> <option value="bar"></option> <option value="baz"></option>
</datalist>

I can imagine a number of use cases for this:

  • “Share this” forms, like the one on Last.fm, that allow you to either select from your contacts on the site, or enter email addresses, separated by commas. Using input type="email" with a multiple attribute, in combination with a datalist would work nicely.
  • Entering the details for an event, where you can either select from a list of venues or, if the venue is not listed, create a new one.
  • Just about any form that has a selection of choices, of which the last choice is “other”, followed by “If other, please specify…”

You can take something like this:

<label for="source">How did you hear about us?</label>
<select name="source"> <option>please choose...</option> <option value="television">Television</option> <option value="radio">Radio</option> <option value="newspaper">Newspaper</option> <option>Other</option>
</select>
If other, please specify:
<input id="source" name="source">

And replace it with this:

<label for="source">How did you hear about us?</label>
<datalist id="sources"> <option value="television"></option> <option value="radio"></option> <option value="newspaper"></option>
</datalist>
<input id="source" name="source" list="sources">

The datalist element has been designed according to one of the design principles driving HTML5—Degrade Gracefully:

On the World Wide Web, authors are often reluctant to use new language features that cause problems in older user agents, or that do not provide some sort of graceful fallback. HTML 5 document conformance requirements should be designed so that Web content can degrade gracefully in older or less capable user agents, even when making use of new elements, attributes, APIs and content models.

Because the datalist element contains a series of option elements with value attributes, it is effectively invisible to user-agents that don’t support the datalist element. That means you can use the datalist element without worrying it “breaking” in older browsers.

If you wanted, you could include a message for non-supporting browsers:

<datalist id="sources"> Your browser doesn't support datalist! <option value="television"></option> <option value="radio"></option> <option value="newspaper"></option>
</datalist>

That message—“Your browser doesn’t support datalist!”—will be visible in older browsers, but browsers that support datalist know not to show anything that’s not an option. But displaying a message like this for older browsers is fairly pointless; I certainly wouldn’t consider it graceful degradation.

In my opinion, one of the best aspects of the design of the datalist element is that you can continue to do things the old-fashioned way—using a select and an input—and at the same time start using datalist. There’s no violation of either; you can use the same option elements for the select and the datalist:

<label for="source">How did you hear about us?</label>
<datalist id="sources"> <select name="source"> <option>please choose...</option> <option value="television">Television</option> <option value="radio">Radio</option> <option value="newspaper">Newspaper</option> <option>Other</option> </select> If other, please specify:
</datalist>
<input id="source" name="source" list="sources">

Browsers that support datalist will display the label “How did you hear about us?” followed by a combo-box text field that allows the user to select an option, or enter some free text.

Browsers that don’t support datalist will display the the label “How did you hear about us?” followed by a drop-down list of of options (the last of which is “other”), followed by the text “If other, please specifiy”, followed by a text field.

Take a look at this example in Opera to see datalist in operation. Take a look at it in any other browser to see the fallback. The source is on Github if you’d like to play around with it.

WebKit’s mistake

If you try that example in any browser, you’ll get something that works; either through datalist support or through the select fallback …unless the browser is using WebKit.

It took me a while to figure out why this would be the case. I didn’t think that Safari or Chrome supported datalist and a little digging around with object detection in JavaScript confirmed this. So why don’t those browsers follow the standard behaviour and simply ignore the element they don’t understand and render what’s inside it instead.

Here’s the problem: line 539 of WebKit’s default CSS:

datalist { display: none;
}

This is pretty much the worst possible behaviour for a browser to implement. An element should either be recognised—like p, h1 or img—and parsed accordingly, or an element is unrecognised—like foo or bar—and ignored. WebKit does not support the datalist element (even in the current nightly build), so the element should be ignored.

Fortunately the problem is easily rectified by adding something like this to your own stylesheet:

datalist { display: inline-block;
}

I’ve submitted a bug report on the WebKit Bugzilla.

Update: That Webkit bug has now been fixed so the extra CSS is no longer necessary.

# Tuesday, January 11th, 2011 at 4:47pm

Clarissa Peterson

Cool, I didn’t know that one. I probably did learn it at some point and forgot it since I don’t do HTML very much anymore.

Related posts

Placehold on tight

Getting consistent browser behaviour for the placeholder attribute.

Accent all areas

A small but important addition to CSS.

Related links

On the styling of forms by Bruce Lawson

Bruce takes a look at the tricky issue of styling native form controls. Help us, Shadow DOM, you’re our only hope!

Tagged with

HTML5 forms (and IE10 (Mobile)) | Andrea Trasatti’s tech notes and more

Andrea looks at support for HTML5 input types in IE10 Mobile.

Tagged with

CSS3 Pseudo-Classes and HTML5 Forms | HTML5 Doctor

A look at the new pseudo-classes in CSS3 that go hand-in-hand with the form enhancements introduced in HTML5.

Tagged with

HTML5 Please

This looks like a handy resource with a shitty, shitty name. Count the number of items that are in HTML (or JavaScript or APIs). Now count the number of items that are in CSS.

Tagged with

Polyfilling The HTML5 Gaps With JavaScript

An in-depth look at browser polyfills: what they are, how they work, and how you can make your own.

Tagged with

Previously on this day

17 years ago I wrote iPhone, uPhone, we all scream for iPhone

Linkage to other people’s thoughts on Apple’s latest gadget.

19 years ago I wrote It's a small world network after all

I’ve been spending most of my time over at Message lately working on a big intranet project. It’s not just a website behind a firewall. It’s more like a desktop application on the web that happens to reside in a walled garden.