Datalist, Fieldset and Legend
Suggest values without locking users in, and group related controls with a real caption.
Two under-used elements make forms feel polished and accessible with almost no effort.
<datalist>: suggestions, not a cage
A <select> forces one of your options. A <datalist> offers autocomplete hints while still letting the user type anything. You wire it up by matching the input's list attribute to the datalist's id.
<input list="fruits" name="fruit">
<datalist id="fruits">
<option value="Apple">
<option value="Mango">
</datalist><fieldset> and <legend>: grouping with meaning
Wrap related controls — especially radio groups — in a <fieldset>, and give it a <legend>. Screen readers announce the legend together with each control, so the user always knows which group they're in. Bonus: disabling a fieldset disables every control inside it at once.
Example
When to use it
- A city search input uses <datalist> to show autocomplete suggestions from a pre-loaded list while still allowing free text.
- A multi-step form uses <fieldset> and <legend> to group related inputs and announce the group name to screen readers.
- A payment form uses a <fieldset> to visually and semantically group card number, expiry, and CVV fields together.
More examples
Datalist for autocomplete suggestions
<datalist> provides a list of suggestions linked to the input by the list/id pairing; free text is still allowed.
<label for="language">Favourite language</label>
<input type="text" id="language" name="language"
list="languages" autocomplete="off">
<datalist id="languages">
<option value="HTML">
<option value="CSS">
<option value="JavaScript">
<option value="Python">
<option value="Rust">
</datalist>Fieldset grouping related inputs
<fieldset> groups related fields; <legend> provides an accessible group label announced by screen readers.
<fieldset>
<legend>Shipping address</legend>
<label for="street">Street</label>
<input type="text" id="street" name="street" required>
<label for="city">City</label>
<input type="text" id="city" name="city" required>
<label for="zip">ZIP code</label>
<input type="text" id="zip" name="zip" pattern="[0-9]{5}" required>
</fieldset>Disabled fieldset for inactive step
disabled on <fieldset> disables all contained inputs at once, useful for multi-step form states.
<fieldset disabled>
<legend>Step 2: Payment (complete step 1 first)</legend>
<label for="card">Card number</label>
<input type="text" id="card" name="card">
<label for="expiry">Expiry</label>
<input type="text" id="expiry" name="expiry">
</fieldset>
Discussion