select, option, optgroup and datalist
Dropdowns done properly: grouping options, multiple selection, the placeholder option trick, and when a datalist beats a select.
-
HTML Basics
- What is HTML: The Structure Layer of Every Web Page
- HTML Document Structure: DOCTYPE, html, head and body
- Elements, Tags and Attributes: The Vocabulary of HTML
- HTML Comments: Notes That Ship With Your Code
- Block Level and Inline Elements
- Writing and Running Your First HTML Page
- How a Browser Turns Markup Into a Page
- Text and Formatting
- Links and Navigation
- Images and Media
- Lists
- Tables
-
Forms
- Form Structure: form, action and method
- Input Types: Text, Email, Number, Date and the Rest
- Labels: The Most Important Element in a Form
- Checkboxes, Radio Buttons and Grouping
- select, option, optgroup and datalist
- textarea, File Uploads and Hidden Fields
- Buttons: submit, reset and button
- Built In Form Validation
- GET or POST: What Happens When a Form Is Submitted
- Semantic HTML
- HTML5 Features
- Head and Metadata
- HTML with CSS
- HTML with JavaScript
- Accessibility
-
HTML SEO
- How Google Works: Crawling, Indexing and Ranking
- SEO Friendly HTML Structure
- Titles and Descriptions That Earn Clicks
- Headings and Content Structure for Search
- Internal Linking and Anchor Text
- robots.txt and XML Sitemaps
- Canonical URLs and Duplicate Content
- Structured Data and JSON-LD
- Image SEO
- Core Web Vitals and Mobile Friendliness
- DevTools and Debugging
- Editor Productivity
- HTML Best Practices
- HTML Projects
- Advanced Projects
- Practice and Exams
Concept
select presents a list of options and lets the reader choose. It is the right control when there are more choices than radio buttons can comfortably show, and the wrong control when there are only two or three.
Syntax
<label for="course">Course</label>
<select id="course" name="course">
<option value="">Please choose</option>
<option value="design">Design</option>
<option value="data">Data science</option>
<option value="civil" selected>Civil engineering</option>
</select>The value is what the server receives; the text between the tags is what the reader sees. Omit value and the visible text is submitted instead, which couples your database to your wording - rename the option and old records stop matching.
The placeholder option
A select always has something selected. Without a first empty option, the first real choice is preselected, and a reader who simply never touches the control submits it without ever deciding.
<select id="course" name="course" required>
<option value="" disabled selected>Please choose a course</option>
<option value="design">Design</option>
<option value="data">Data science</option>
</select>Three attributes working together: value="" makes required reject it, selected makes it the initial state, and disabled stops the reader returning to it after choosing.
optgroup
<select id="course" name="course">
<option value="">Please choose</option>
<optgroup label="Design">
<option value="product">Product design</option>
<option value="comms">Communication design</option>
</optgroup>
<optgroup label="Engineering">
<option value="civil">Civil</option>
<option value="mech">Mechanical</option>
</optgroup>
</select>The group label is announced by screen readers and shown as a non selectable heading. Groups cannot nest, and an option can belong to only one.
Multiple selection
<label for="skills">Skills</label>
<select id="skills" name="skills[]" multiple size="6">
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="js">JavaScript</option>
</select>Honest advice: multiple is a poor control. Selecting more than one requires holding Ctrl or Cmd, which most people do not know, and it is close to unusable on touch. A group of checkboxes does the same job and everyone understands it. Reach for multiple only when the list is long and the reader is expected to be a power user.
Note the [] in the name, which is the PHP convention for receiving an array. Other server languages have their own.
datalist
datalist gives a text input a list of suggestions while still allowing anything to be typed. It is not a dropdown - it is autocomplete.
<label for="city">City</label>
<input list="cities" id="city" name="city" autocomplete="off">
<datalist id="cities">
<option value="Ahmedabad">
<option value="Bengaluru">
<option value="Chennai">
<option value="Pune">
</datalist>The list attribute on the input matches the id of the datalist. Options here are void - no closing tag and no text content, just a value.
select | datalist | |
|---|---|---|
| Reader can type a new value | No | Yes |
| Restricted to the list | Yes | No |
| Filters as you type | Partially | Yes |
| Consistent across browsers | Reasonably | No - varies a lot |
Use select when the value must be one of the options. Use datalist when the list is a convenience and free text is acceptable.
Example
<p>
<label for="state">State</label>
<select id="state" name="state" required autocomplete="address-level1">
<option value="" disabled selected>Select a state</option>
<optgroup label="West">
<option value="GJ">Gujarat</option>
<option value="MH">Maharashtra</option>
</optgroup>
<optgroup label="South">
<option value="KA">Karnataka</option>
<option value="TN">Tamil Nadu</option>
</optgroup>
</select>
</p>Short codes as values keep the data stable while the visible names stay readable and translatable.
Styling reality
The open dropdown list is drawn by the operating system, not by the page, so it cannot be styled. The closed control can be, within limits:
select {
appearance: none; /* remove the native arrow */
padding: 0.5rem 2rem 0.5rem 0.75rem;
border: 1px solid #94a3b8;
border-radius: 6px;
background-image: url("data:image/svg+xml,..."); /* your own arrow */
background-repeat: no-repeat;
background-position: right 0.6rem center;
}Custom dropdown components built from div elements can be styled completely, but they must reimplement keyboard navigation, type ahead, screen reader announcements and touch behaviour. That is a substantial amount of work, and most attempts are worse than the native control.
Important rules
- A
selectalways has a value; there is no empty state without an empty option. sizegreater than one turns it into a list box rather than a dropdown.optgroupcannot nest.- A disabled option cannot be chosen; a disabled
selectsubmits nothing. - The dropdown list itself cannot be styled.
- Only
optionandoptgroupmay go inside aselect.
Common mistakes
- No placeholder option, so the first real choice is submitted by default.
- Omitting
valueand submitting display text. - Using a
selectfor two options where radio buttons are faster and clearer. - Using
multiplewhere checkboxes belong. - Building a custom dropdown and losing keyboard support.
- A list of two hundred options with no grouping and no search.
Best practices
- Two or three options: radio buttons. Four to about fifteen: a select. More than that: a datalist or a search field.
- Always include a disabled placeholder option when the field is required.
- Give every option a stable
valueindependent of its label. - Group long lists with
optgroup. - Order options usefully - by frequency, or alphabetically, never randomly.
- Prefer the native control; the cost of replacing it is higher than it looks.
Practice
- Build a select with a disabled placeholder and confirm
requiredblocks submission until a real choice is made. - Group fifteen options into three
optgroupsections. - Build the same choice twice, once as a select and once as radio buttons, and compare how each feels on a phone.
- Add a datalist to a city field and try typing a value that is not in the list.