Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

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.

Levels: Beginner, Intermediate, Advanced ~45 min read

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.

Interactive Runnable example
Edit

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.

html
<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

The attributes on <option> describe different parts of an option.

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

html
<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.

html
<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.

html
<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

html
<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.

html
<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.

html
const option = document.querySelector("#theme option[value="light"]");
console.log(option.defaultSelected); // true
console.log(option.selected);        // may become false

The 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.

html
<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.”

html
<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.

html
<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.

html
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

html
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.

html
<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.

html
<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

html
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

html
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.

Was this page helpful?

Mark this learning resource complete to track your learning progress.