The <select> Element
A comprehensive beginner-to-guru lesson on the HTML <select> element, options, grouping, selection state, form behavior, accessibility, DOM APIs, and customizable select controls.
Basic
The <select> element gives users a native control for choosing one or more values from a defined set of options. It is a form-associated element with browser- and platform-native interaction, rather than merely a styled list of links or buttons.
Output
Ready to run.
What <select> represents
A select represents a choice control. The control itself owns the selection state; its child <option> elements define the available choices, and <optgroup> can organize those choices into labeled groups.
<label for="language">Language</label>
<select id="language" name="language">
<option value="en">English</option>
<option value="fr">French</option>
<option value="ar">Arabic</option>
</select>Quick check
Complete the form control with the element that presents a set of options for selection.
<label for="language">Language</label>
< id="language" name="language">
<option>English</option>
</select>
Mode | Selection model | Typical use |
|---|---|---|
Single selection | At most one option is selected | Choose one value |
multiple | Zero or more options may be selected | Choose several values |
Customizable select | Native select semantics with customizable rendering features | Customize presentation while preserving the select model |
The element is not self-closing
Unlike <input>, <select> is not a void element. It has an opening and closing tag because its options and related child elements live inside it.
<select name="plan">
<option value="free">Free</option>
<option value="pro">Pro</option>
</select>A select needs options
The useful choices of a select are represented by option elements. An optgroup can group options, while the newer customizable-select model can also introduce a button and selectedcontent for the closed control presentation.
Single selection by default
Without multiple, a select normally represents one selected option at a time. The first option is selected by default when no option has been selected otherwise, subject to the HTML selection rules.
<select name="theme">
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>Multiple selection
The multiple attribute changes the control so more than one option can be selected. This changes the interaction model, the DOM APIs you use, and the form-submission shape.
<select name="topics" multiple>
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="js">JavaScript</option>
</select>Output
Ready to run.
Labels are part of the interface contract
A select should have an accessible label. The clearest authoring pattern is an explicit label whose for value matches the select id, although a wrapping label can also provide the association.
<label for="country">Country</label>
<select id="country" name="country">
<option value="eg">Egypt</option>
<option value="fr">France</option>
</select>id and name do different jobs
The id identifies the element in the document and is used by mechanisms such as explicit labels. The name identifies the form data name and is important when the selected value is submitted.
Basic option syntax
An option normally has visible text and an explicit value. Supplying value is recommended when the submitted value should be stable and should not depend on the option text.
<option value="beginner">Beginner</option>Option value fallback
If an option has no value attribute, its value is derived from its text according to the HTML option-value rules. For maintainable forms, explicitly setting value makes the data contract clearer.
The selected attribute is a default
The selected attribute declares an option as selected by default in markup. It is not the same conceptual thing as the live selectedness of an option after the user or script changes the selection.
<select name="level">
<option value="beginner">Beginner</option>
<option value="advanced" selected>Advanced</option>
</select>Placeholder label options
A required single-select can use an empty-value first option as a placeholder label option. The important distinction is that this is a choice-control technique, not a substitute for the select element’s accessible label.
<label for="role">Role</label>
<select id="role" name="role" required>
<option value="">Choose a role</option>
<option value="author">Author</option>
<option value="reviewer">Reviewer</option>
</select>Grouping choices with optgroup
Use optgroup when the options form meaningful labeled groups. Users cannot select an optgroup itself; it organizes options for the control’s interface.
<select name="course">
<optgroup label="HTML">
<option value="html-foundations">HTML Foundations</option>
<option value="html-forms">HTML Forms</option>
</optgroup>
<optgroup label="CSS">
<option value="css-layout">CSS Layout</option>
</optgroup>
</select>Disabled groups
An optgroup can be disabled, preventing its contained options from being chosen. This is useful when a category exists conceptually but is temporarily unavailable.
The select itself can be disabled
The disabled attribute prevents user interaction and changes form-control participation. A disabled select is not simply a read-only select with a different visual style.
<label for="edition">Edition</label>
<select id="edition" name="edition" disabled>
<option>Coming soon</option>
</select>Required selection
The required attribute makes the control subject to the required-selection constraint. For a single select, a common pattern is an initial placeholder option with an empty value so the user must choose a real value.
Autofocus
autofocus can request initial focus for the select when the document loads. Because focus is a scarce interaction resource, use it deliberately rather than automatically on every form.
Autocomplete
autocomplete can provide a hint for user-agent autofill behavior. Its meaning is part of the broader form-control autocomplete model; it is not a guarantee that a browser will fill a particular value.
Form association
A select can belong to a form through DOM ancestry or through its form attribute. The explicit form association is useful when the control is not physically inside the form element.
<form id="profile" action="/save">
<button>Save</button>
</form>
<label for="timezone">Timezone</label>
<select id="timezone" name="timezone" form="profile">
<option value="utc">UTC</option>
</select>Intermediate
Now move from basic authoring to the selection model, sizing, option state, grouping, and form behavior that make select controls predictable.
size changes the presentation model
The size attribute can request a visible number of options. A value greater than one participates in the list-box presentation model rather than the usual single-line dropdown presentation.
<select name="language" size="4">
<option>English</option>
<option>French</option>
<option>Arabic</option>
<option>Spanish</option>
</select>multiple and size are related but not identical
multiple determines whether multiple options may be selected. size controls the requested visible list size. Either can affect the user interface, but they express different semantics.
Option disabled state
An individual option can be disabled. A disabled option remains part of the option set but cannot be selected by the user.
<select name="plan">
<option value="free">Free</option>
<option value="pro" disabled>Pro — unavailable</option>
</select>Option labels
An option may have a label attribute that supplies its user-visible label. The option’s value remains a separate concept used for the option’s data value.
The selected option is not the same as selected markup
HTML has a distinction between an option’s defaultSelected state, represented by the selected attribute, and its live selected state. User interaction changes live selectedness without rewriting the original markup.
The select value
For a single-select, the HTMLSelectElement value property represents the value of the first selected option, or an empty string when there is no selected option.
const select = document.querySelector("select");
console.log(select.value);Output
Ready to run.
selectedIndex
selectedIndex exposes the index of the first selected option in the select’s options list. It is useful when code needs the selected option’s position rather than only its value.
The options collection
HTMLSelectElement.options exposes the select’s option collection. It lets scripts inspect, add, remove, and reason about the option set through the DOM API.
const select = document.querySelector("#country");
for (const option of select.options) {
console.log(option.value, option.text, option.selected);
}selectedOptions
selectedOptions exposes the options currently selected. This becomes especially important for multiple selects because value only reports the first selected option.
const selected = [...select.selectedOptions].map(option => option.value);
console.log(selected);Setting value in JavaScript
Assigning select.value asks the browser to select the option whose value matches. If no matching option exists, the resulting value is the empty string rather than creating a new option.
select.value = "advanced";Setting option.selected
An option’s selected property represents live selectedness and can be changed by script. When working with multiple selections, setting individual options can be useful because several options may be selected simultaneously.
Change events
The change event is the usual high-level event for reacting to a committed select choice. Its timing depends on the control’s interaction model and user-agent behavior, so code should respond to the semantic event rather than assume a particular pointer sequence.
select.addEventListener("change", event => {
console.log(event.currentTarget.value);
});Input events
Current browser APIs also expose input events for select controls. This is useful when code needs to observe value changes as part of the general form-control event model; choose the event whose timing matches the behavior you actually need.
Constraint validation
Select is a submittable, resettable, form-associated element and participates in native constraint validation when applicable. required is the main select-specific constraint authors commonly encounter.
Form submission
A selected option can contribute a name/value pair when the select is a successful form control. A disabled select does not participate in form submission. Multiple selections produce multiple values for the same control name.
<form action="/search" method="get">
<label for="tag">Tag</label>
<select id="tag" name="tag" multiple>
<option value="html" selected>HTML</option>
<option value="css" selected>CSS</option>
</select>
<button>Search</button>
</form>Reset behavior
Select participates in form reset behavior. Reset returns selection state toward the defaults established by the option selected attributes and the select’s reset algorithm; it does not mean “undo the last user click.”
DOM order matters
The option list is defined from the select’s relevant descendant options, including options in optgroups. Scripts that depend on numeric indexes should remember that adding, removing, or regrouping options can change those indexes.
Option text and option value
The text users see and the value submitted are related but separate. A mature form design chooses human-readable labels and stable machine-facing values independently.
<option value="html5-forms">Forms and Form Controls</option>Do not encode business meaning only in visible text
Visible wording can change for clarity, localization, or product language. A stable value makes downstream processing less dependent on presentation text.
Empty values need intentional handling
An option with an empty value is often appropriate for a placeholder state. Application code should distinguish “the user has not selected a real value” from a legitimate domain value that happens to be empty, if the domain permits one.
Optgroup is organization, not selection
Users select options, never optgroups. Treat an optgroup label as organizational context for its descendants, not as a selectable category value.
Horizontal rules inside select
The current HTML model permits hr in select controls as a decorative separator. It is not a selectable value and should not be treated as a semantic option.
Advanced select content model
Modern HTML expands the select content model beyond the traditional option/optgroup-only mental model. A dropdown may have a button as its first child, and that button may contain selectedcontent. Script-supporting and certain structural elements also have specification-defined roles in the content model.
Customizable select controls
The customizable select model lets authors build richer closed-control presentation while retaining a native select’s underlying selection semantics. This is a major architectural distinction: customize the native control rather than replacing it with an unrelated widget when native behavior is sufficient.
<select>
<button>
<selectedcontent></selectedcontent>
</button>
<option value="one">One</option>
<option value="two">Two</option>
</select>selectedcontent reflects the selected option
selectedcontent declaratively reflects the contents of the currently selected option inside the select’s button. The standard clones the selected option’s child structure; it does not simply copy the option label attribute.
selectedcontent and multiple
The enabled selectedcontent mechanism applies to a single-select dropdown model. The specification explicitly does not use it for a multiple select.
Option markup inside customizable select
Modern option content can participate in richer visual presentation, but authors still need to preserve a clear accessible and user-facing label/value relationship. Do not let decorative structure obscure the actual choice.
Advanced
At the expert level, the goal is to understand the select state model, its DOM interfaces, form-control algorithms, and the boundary between native semantics and browser presentation.
HTMLSelectElement is the control API
JavaScript exposes a select through HTMLSelectElement. This interface provides properties such as value, selectedIndex, options, selectedOptions, multiple, size, disabled, required, and form, plus methods for manipulating the option set and validation state.
The first selected option matters for value
For HTMLSelectElement.value, the browser returns the value of the first selected option. That detail is critical for multiple selects: value alone is not a complete representation of all selected values.
Multiple values require selectedOptions or options
For a multiple select, inspect selectedOptions or filter the options collection by selectedness. This produces the complete set of selected choices rather than silently discarding all but the first.
const values = Array.from(select.selectedOptions, option => option.value);Option selectedness versus defaultSelected
HTMLOptionElement exposes defaultSelected for the markup-level default and selected for live state. This distinction mirrors the broader form-control principle that initial state and current state are not interchangeable.
Programmatic selection can change other options
For a single select, establishing one option as selected can affect the selectedness of other options because the control permits only one selected option in that mode. Code should reason about the select as a selection model, not as independent booleans.
Validity state
The select participates in the standard constraint-validation API. Code can inspect validity and use reportValidity or checkValidity at the appropriate application boundary, while native required behavior remains defined by HTML.
if (!select.checkValidity()) {
select.reportValidity();
}WillValidate and disabled controls
Form-control APIs expose whether a control participates in constraint validation. Disabled controls are outside normal validation participation, which is one reason disabled and required should never be treated as interchangeable states.
Form owner is an association, not necessarily a parent
The select’s form owner can be established by its nearest ancestor form or explicitly through the form attribute. This is a recurring HTML form-control concept that also applies to input and textarea.
Browser UI is not HTML semantics
The popup, arrow, keyboard interaction details, native typography, and platform-specific presentation are partly user-agent UI. CSS and modern customizable-select features can influence presentation, but HTML semantics remain the source of the control’s meaning.
Keyboard behavior is platform-sensitive
Do not build application logic around a single browser’s exact key sequence for opening, navigating, or committing a select. Rely on the control’s semantic events and native interaction model.
Accessibility starts with native semantics
A native select already exposes selection semantics and state to assistive technologies. Preserve that semantic control when it meets the product requirement instead of recreating a listbox or combobox from generic elements without a compelling reason.
Do not replace select with a pile of divs casually
A custom div-based selector inherits responsibility for keyboard navigation, focus management, selection state, announcements, disabled states, form integration, and many edge cases. Native select avoids much of that complexity.
CSS is presentation, not selection semantics
Use CSS to style the control within the capabilities of the browser and the selected implementation model. Do not teach width, font, borders, or visual affordances as if they changed what the HTML select means.
Dynamic option creation
Scripts can create options with the Option constructor or create elements directly, then add them to a select. Dynamic forms should still preserve stable values, labels, ordering, and accessibility.
const option = new Option("Python", "python");
select.add(option);Do not trust client-side option values
The browser can submit a value from a select, but the server must treat submitted data as untrusted input. A malicious client can alter or bypass the control entirely, so authorization and domain validation must occur on the server when security matters.
Internationalization
Visible option labels may need localization while submitted values often need to remain stable across languages. Keep the machine-facing value independent from translated UI text unless the domain explicitly requires otherwise.
Right-to-left interfaces
A select participates in document and element directionality like other form controls. Test RTL presentation with the actual browsers and native UI combinations you support; do not assume a single CSS screenshot captures all platform behavior.
Common authoring mistakes
Using a select when users need free-form text rather than a bounded set of choices.
Forgetting a real accessible label.
Using visible option text as the only machine-facing data contract.
Using selected as though it were a permanent live-state flag.
Using value for a multiple select and accidentally reading only the first selection.
Assuming disabled means readonly or that disabled values will be submitted.
Using optgroup as though users can select a group.
Treating a placeholder option as the label for the control.
Replacing native select semantics with a custom widget without accounting for accessibility and form behavior.
Assuming browser-native popup styling is identical everywhere.
A production select checklist
Choose select only when the allowed choices are bounded enough to justify a choice control.
Give the control a real label.
Give it an id when other markup needs to reference it.
Give it a stable name when its value belongs in form submission.
Give options explicit stable values.
Use selected only for intentional defaults.
Use required and an empty placeholder option when a real choice is mandatory.
Use multiple only when multiple values genuinely make sense.
Use optgroup for meaningful option categories.
Treat disabled controls as non-submitting and non-interactive.
Handle multiple selections through selectedOptions or the options collection.
Test keyboard, screen-reader, mobile, RTL, and browser behavior for important forms.
Validate and authorize submitted values on the server.
Where this lesson stops
This lesson owns the select element and its immediate option/optgroup/selectedcontent relationships. The dedicated option, optgroup, and selectedcontent lessons will go deeper into those elements individually. Cross-element validation and submission rules remain separate curriculum units.
Final mental model
Think of <select> as a native selection state machine with a defined option list, not as a styled container. The HTML structure declares choices and defaults; the live DOM exposes current selection; browser UI handles interaction; and form submission turns the selected state into data according to HTML’s form-control rules.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.