The <option> Element
A comprehensive beginner-to-guru lesson on the HTML <option> element, labels, values, default and live selection state, disabled options, select and datalist relationships, DOM APIs, customizable selects, accessibility, and form data contracts.
Basic
The <option> element represents one choice in a <select>, or one suggestion in a <datalist>. It looks simple, but it owns several important distinctions: its visible label, submitted value, default selectedness, live selectedness, disabledness, and DOM state are related without being interchangeable.
Output
Ready to run.
The specification, translated
The HTML standard treats <option> as a choice or suggestion whose behavior depends on its parent. Inside <select>, it participates in selection and form submission; inside <datalist>, it supplies a suggestion. Its label, value, default selectedness, current selectedness, and disabled state are separate pieces of information. In practice: use the visible label to help people choose, use value for stable data, use selected for the current state, and use disabled when the choice is unavailable.
What <option> represents
An option is not a generic list item. Its meaning comes from its parent context: inside <select> it is a choice the user can select; inside <datalist> it contributes a suggestion for an input. The same element therefore participates in two different control models.
<select name="language">
<option value="en">English</option>
<option value="fr">French</option>
</select>Quick check
Complete the select with the element that represents one selectable option.
<select>
< value="en">English</option>
</select>
Where <option> can appear
Attribute / state | Meaning | Important distinction |
|---|---|---|
label | Presentation label when applicable | Not the same thing as the submitted value |
value | Value associated with the option | Used for submission when the option is selected |
selected | Initial/default selectedness in markup | Live selectedness can change independently |
disabled | Makes the option unavailable for selection | Does not mean the option ceases to exist |
The current HTML standard permits an option as a descendant of <select>, <optgroup>, or <datalist>. The exact content model depends on whether label/value attributes are present and whether the option belongs to a datalist.
Basic syntax
<option value="python">Python</option>The text normally supplies the human-facing label. An explicit value gives the application a stable machine-facing value. For production forms, those two roles should usually be deliberately separated.
Content model and current markup rules
The current standard allows different option content depending on its attributes and context. If both label and value are present, the option has no text content model; if label is present without value, text is allowed; and options without label can use text or, in the customizable-select model, restricted phrasing/div content. Do not assume every visually possible child is valid HTML.
Tag omission
In text/html, an option end tag may be omitted in specific cases, such as before another option or optgroup, or at the end of its parent. Explicit end tags are generally clearer for teaching, maintenance, and generated content.
The label attribute
The label attribute supplies the option’s user-visible label. When it is absent, the label is derived from the option’s text. The current specification requires a specified label not to be empty.
<option value="gb" label="United Kingdom"></option>For normal native selects, label and text should not be treated as two unrelated UI strings. In the customizable-select model, the distinction becomes especially important because selectedcontent reflects the option’s DOM content rather than simply the label attribute.
The value attribute
The value attribute supplies the option’s value for form submission and for the option’s value IDL property. If the attribute is omitted, the option’s value is derived from its text content.
<option value="py">Python</option>
<option>JavaScript</option>The first option submits the stable value py. The second derives its value from its text. Explicit values are usually safer because changing visible wording or localization should not silently change a backend data contract.
Label versus value
label answers: “What should the user see?”
value answers: “What data should this choice represent?”
text content can supply the fallback label and, when value is absent, the fallback value.
Quick check
Complete the option so that the form submits the stable value py while showing Python to the user.
<option value="">Python</option>
Build a stable data contract
<option value="egypt">Egypt</option>
<option value="united-kingdom">United Kingdom</option>
<option value="united-states">United States</option>A localized interface can translate the visible labels while retaining the same values. This prevents a language change from becoming a data migration.
The selected attribute is a default, not permanent live state
The selected content attribute declares default selectedness in markup. It does not mean the option can never become unselected. User interaction and script can change the live selectedness.
<select name="theme">
<option value="light" selected>Light</option>
<option value="dark">Dark</option>
</select>defaultSelected versus selected
HTMLOptionElement.defaultSelected reflects the selected content attribute. HTMLOptionElement.selected represents current selectedness. After a user changes the selection, those values can legitimately differ.
const option = document.querySelector("#theme option[value="light"]");
console.log(option.defaultSelected); // true
console.log(option.selected); // may become falseThe disabled attribute
A disabled option is unavailable for user selection. An option can be disabled directly with its own disabled attribute or become disabled because it is inside a disabled optgroup.
<select name="plan">
<option value="free">Free</option>
<option value="legacy" disabled>Legacy</option>
</select>An option disabled by an ancestor optgroup does not acquire its own disabled content attribute. This matters when inspecting HTMLOptionElement.disabled and when designing DOM logic.
Disabled does not mean immutable
The standard does not make disabled options completely frozen. Script can modify their DOM state, including selectedness. Disabled primarily describes user interaction and participation rules, not a universal prohibition on DOM mutation.
Placeholder label options
In certain single-select configurations, an option can serve as the select’s placeholder label option. This is not the same thing as the select’s accessible label. A placeholder option is a choice-control state used to represent “nothing chosen yet.”
<label for="country">Country</label>
<select id="country" name="country" required>
<option value="">Choose a country</option>
<option value="eg">Egypt</option>
<option value="fr">France</option>
</select>The explicit label remains the control label. The empty option gives the required select an initial state that does not satisfy the required value requirement.
Options inside a multiple select
A multiple select may have several options selected at once. Each selected option can contribute a submitted value. The option itself still represents one choice; the multiplicity belongs to the owning select.
<select name="topics" multiple>
<option value="html" selected>HTML</option>
<option value="css">CSS</option>
<option value="js" selected>JavaScript</option>
</select>Selection is live state
An option’s selected property reflects current selectedness. Changing it can change the owning select’s state and, for a single select, can cause another option to become unselected.
const option = document.querySelector("option[value="js"]");
option.selected = true;The option index
HTMLOptionElement.index exposes the option’s position in the owning select’s options list. Do not confuse this with an option’s business identifier or submitted value.
The form property
An option associated with a select exposes the same form relationship through its form property. The option does not become an independent form control; the owning select remains the form-associated control.
The text IDL property
HTMLOptionElement.text exposes the option’s text in a form intended for its label-like text, with whitespace handling different from raw textContent. Use the property that matches the question you are actually asking.
Core HTMLOptionElement properties
disabled — reflects the option’s own disabled attribute.
form — exposes the associated form through the owning select.
label — reflects the label attribute.
defaultSelected — reflects the selected attribute.
selected — exposes current selectedness.
value — exposes the option value.
text — exposes option text.
index — exposes the option’s position in the select option list.
Creating options with JavaScript
const option = new Option("Python", "python", true, true);
select.add(option);The Option constructor accepts text, value, defaultSelected, and selected. The two boolean arguments are intentionally separate: defaultSelected changes the selected attribute, while selected controls the live selected state.
Constructor subtlety
Passing true for defaultSelected does not by itself guarantee that the option is currently selected if the selected argument is omitted. When creating options programmatically, be explicit about both default and live state when both matter.
Option inside datalist
Inside a datalist, an option supplies a suggestion rather than a select choice. Its selectedness does not act as the user’s chosen input value in supporting browsers.
<label for="browser">Browser</label>
<input id="browser" name="browser" list="browsers">
<datalist id="browsers">
<option value="Firefox">
<option value="Chrome">
<option value="Safari">
</datalist>Do not transfer select assumptions to datalist
A datalist option participates in a suggestion list, not the select selection state machine. Features such as selected defaults that matter to select options do not become a second way to set an input’s current value.
Relationship with optgroup
Inside a select, optgroup provides a labeled grouping boundary around options. The optgroup itself is not selectable. Its disabled attribute can make descendant options unavailable to users.
<select name="size">
<optgroup label="Small">
<option value="s">Small</option>
</optgroup>
<optgroup label="Large">
<option value="l">Large</option>
</optgroup>
</select>The hr boundary
The current select model also permits hr separators between option groups in the relevant select content model. An hr is presentation/separation within the control; it is not an option and cannot be selected or submitted.
Options in customizable selects
Modern HTML also defines a customizable select model. In that model, option content can participate in richer button/popup presentation, while the option still remains the semantic choice and keeps its label, value, disabled, and selectedness concepts.
selectedcontent and option content
When a select uses an enabled selectedcontent element, the selected option’s DOM structure can be cloned into that selectedcontent region. This is different from simply reading the option’s label attribute.
Therefore, if you design rich option content, understand which parts are semantic data, which parts are visual content, and what gets cloned into the selected control surface.
The label attribute does not become selectedcontent content
The current standard specifically distinguishes an option’s label from its DOM content for selectedcontent cloning. Do not assume that setting label controls every visual representation of the selected option in a customizable select.
Interactive content restrictions
Option content is deliberately constrained. Do not put arbitrary interactive controls inside an option and expect them to behave like independent widgets. The option is already part of another interactive control model.
Accessibility
Native option semantics are valuable because browsers and assistive technologies understand the select/option relationship. Start with native semantics rather than rebuilding the control from divs, buttons, and ARIA.
The option label must communicate the choice clearly. If the visible label is ambiguous, changing its CSS or adding decorative content does not fix the underlying information architecture.
Localization
Translate user-facing labels without changing stable values unless the value itself is intentionally localized. Avoid making backend identifiers depend on English, French, Arabic, or other visible strings.
RTL and bidirectional text
Option text participates in the document’s directionality and Unicode bidirectional behavior. Test real Arabic or mixed-direction labels in the browsers and platforms you support rather than judging correctness from one desktop screenshot.
CSS and browser-native presentation
Traditional option styling has historically been limited and varies by browser and operating system. Current customizable-select features provide a newer path for richer presentation, but that does not erase the semantic and content-model rules of option.
Security and trust boundaries
Option values come from the page and can be modified by the client. Never treat a submitted option value as proof that the user is authorized to perform the corresponding action. Validate allowed values and permissions on the server.
Dynamic option generation
const option = new Option("Python", "python");
option.disabled = false;
select.add(option);When generating options dynamically, keep the same separation between display label and stable value that you would use in static HTML. Also update selected/default state deliberately rather than relying on accidental browser behavior.
Mutation and live state
Changing selected, disabled, label, or value through DOM APIs changes the live object and can affect the owning select. Attribute changes and IDL property changes are related, but not every property represents the same layer of state.
Form reset
Form reset restores controls toward their default state. For options, the selected attribute establishes default selectedness; the live selected property can have changed since page load. This is why reset behavior should be tested rather than inferred from the current selected property.
Submission
An option does not submit by itself. When a select is a successful form control, selected options provide the select’s submitted values according to the form submission algorithm. Disabled controls and disabled options have distinct effects that should not be conflated.
Reading multiple selections
const values = [...select.selectedOptions].map(option => option.value);For a multiple select, do not rely on select.value when your requirement is “all selected values.” The value property represents the first selected option; selectedOptions gives you the collection of selected options.
Common authoring mistakes
Using visible text as a backend identifier when a stable value is needed.
Treating selected as the permanent current state instead of a default.
Assuming an optgroup is itself selectable.
Assuming disabled prevents every programmatic mutation.
Using an option placeholder as a substitute for the select’s accessible label.
Putting interactive controls inside option content.
Assuming datalist options behave like select options.
Assuming legacy option CSS behavior is identical across browsers and operating systems.
Trusting client-provided option values for authorization.
Forgetting that localization can change visible labels without changing stable values.
A practical debugging method
Inspect the option’s selected and defaultSelected properties separately.
Inspect value, label, and text separately.
Check whether disabled comes from the option itself or an ancestor optgroup.
Check the owning select and its form relationship.
For multiple selects, inspect selectedOptions rather than only value.
Test reset behavior after changing selection.
Test both select and datalist contexts when the same option data is reused.
Guru practice challenge
Build a localized country select with an explicit control label, a required empty placeholder option, two optgroups, one disabled option, stable machine-facing values, and a multiple-select variant. Then write JavaScript that reports each selected option’s label, value, selected state, defaultSelected state, disabled state, and index. Finally, reset the form and observe which properties return to their defaults.
Production option checklist
Give each meaningful select option an intentional stable value.
Treat visible label and submitted value as separate concepts.
Use selected only when you intentionally define default selection.
Use disabled when a choice should not be user-selectable.
Use optgroup for meaningful categories, not decorative nesting.
Keep datalist behavior separate from select behavior.
Use native option semantics before considering custom widgets.
Test customizable-select content rules before using rich option markup.
Test localization and RTL presentation.
Validate submitted values and permissions on the server.
Where this lesson stops
This lesson owns the <option> element itself and its direct relationships with <select>, <optgroup>, and <datalist>. The dedicated lessons for those elements cover their own deeper rules. Cross-element form validation and form submission remain separate curriculum units.
Final mental model
Think of <option> as one semantic choice/suggestion whose presentation, data value, default state, live state, and availability are separate dimensions. HTML declares the option; the owning control manages selection; the DOM exposes live state; and form algorithms determine what data is submitted.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.