Have you ever had a form that needed to accept a short, arbitrary bit of text? Like a name or whatever. That’s exactly what <input type="text">
is for. There are lots of different input types (and modes!), and picking the right one is a great idea.
But this little story is about something else and applies to any of them.
What if the text needs to be arbitrary (like “What’s your favorite color?”) so people can type in whatever, but you also want to be helpful. Perhaps there are a handful of really popular answers. Wouldn’t it be nice if people could just select one? Not a <select>
, but a hybrid between an input and a dropdown. Hold on though. Don’t make your own custom React element just yet.
That’s what <datalist>
is for. I just used it successfully the other day so I figured I’d blog it because blogging is cool.
Here are the basics:
See the Pen
Basic datalist usage by Chris Coyier (@chriscoyier)
on CodePen.
The use case I was dealing with needed:
- One
<input type="text">
for a username - One
<input type="text">
for a “flag” (an aribtrary string representing a permission)
I probably wouldn’t do a <datalist>
for every username in a database. I don’t think there is a limit, but this is sitting in your HTML, so I’d say it works best at maybe 100 options or less.
But for that second one, we only had maybe 3-4 unique flags we were dealing with at the time, so a datalist for those made perfect sense. You can type in whatever you want, but this UI helps you select the most common choices. So dang useful. Maybe this could be useful for something like a gender input, where there is a list of options you can choose, but it doesn’t enforce you actually choose one of them.
Even lesser known than the fact that <datalist>
exists? The fact that it works for all sorts of inputs besides just text
, like date
, range
, and even color
.
I’d recommend against using labels (“The color of the sky” in your demo) until Mozilla fixes Bug 869690. The issue in Firefox is that if the user types “b,” there is no suggestion for “blue” because Firefox matches user input against the label, not the value, when a label is provided.
Wow! Good catch. That issue was opened 6 years ago… and still isn’t resolved.
This video (from the thread) is both hilarious and painful… https://bug869690.bmoattachments.org/attachment.cgi?id=9055574
At first I was wondering if we might assume the label will always be visible, and include it by default (matching the value), and then maybe use an actual
<label></label>
element for added context. But the results in a quick test were, again… unexpected…Strangely the behavior in FF in that case actually makes more sense, while the result in Chrome is just plain weird!
I love datalist – I would use it even for a larger selection like country – but I don’t like that you can’t style the input arrow, or the dropdown look at all. Like, maybe I want a datalist with countries and I would like to show the flag before the countries in the dropdown – there is no way to do that. That’s a big and needless limiting factor.
I dislike that the dropdown does not look anything like the browser’s “select” dropdown. I was able to style the component to match our other dropdowns, but the menu itself is completely different and apparently unstylable. See https://codepen.io/smlombardi/pen/XvpGrb?editors=1100#0
Looks like Safari has a bug where it shows both datalist and auto-fill suggestions (these are my contacts from address book).
What a great find! I got really excited until I found that it doesn’t really support multiple input items, e.g. “red, green, blue” except in the case of emails… really odd.
I found a neat trick for after being stumped for a few days. It turns out the pattern attribute will filter the available options in the list. I’m using one datalist to provide the same options to various inputs, and the pattern allows me to control which options appear in a given input.
It’s important to note that input patterns are case-sensitive. So, pattern=”na” would not allow to appear.