skip to content

In an HTML <select>, what value does a chosen <option> submit, and how do you control which option is selected when the page first loads?

level: juniorimportance: should knowfreq 52%

answer

  1. name on the select, value on the option
  2. attribute first, text content as fallback
  3. selected sets the starting choice
  4. nothing marked selected is not nothing
  5. optgroup label groups, never nests

basics

~20 s

An option submits its value attribute, or its text content when no value attribute is present. The selected attribute sets the initial choice; a dropdown with nothing marked selected falls back to its first non-disabled option.

solid answer

~40 s

A `<select>` carries the `name`; each chosen `<option>` supplies the value. An option's submitted value is its `value` attribute if it has one, and otherwise the option's own text content — so `<option>Blue</option>` submits `Blue`. You choose the initial state in markup with the `selected` attribute on one option; there is no `value` attribute on the `<select>` tag itself, only a `value` property in the DOM. If no option is marked `selected`, a single-line dropdown is never empty: the browser selects the first option that is not disabled, which is why a "Choose one…" placeholder is written as a real first option with an empty value. `<optgroup label="…">` groups options under a non-selectable heading, and `disabled` on an optgroup disables every option inside it.

code

html · 11 lines
html
<label for="country">Country</label>
<select id="country" name="country">
  <option value="" selected disabled>Choose one…</option>
  <optgroup label="Europe">
    <option value="gb">United Kingdom</option>
    <option value="de">Germany</option>
  </optgroup>
  <optgroup label="Asia" disabled>
    <option value="jp">Japan</option>
  </optgroup>
</select>

go deeper

for a junior

Be ready to say that the name is on the select and the value comes from the chosen option, and that an option without a value attribute submits its text. Know that selected picks the starting option.

for a middle

Explain the fallback chain — value attribute, then text content — and why a single-line select always has something selected. Be able to justify the empty-value placeholder pattern and describe what optgroup adds semantically.

for a senior

Show judgment about data stability: explicit option values so copy edits and translations cannot change what the server stores, and a representable "not answered" state. Be able to argue when multiple is the wrong control and what a hand-built replacement would have to reproduce.

for a principal

Own the tradeoff between a native select and a designed custom picker across a product: what native gives you on mobile, in assistive technology and in form participation, what a custom control costs to build and test forever, and where the line sits for your team.

## What a select is made of `<select>` is a control whose choices are its `<option>` children, optionally clustered inside `<optgroup>` elements. The `name` lives on the `<select>`, not on the options — the options only supply the value: ```html <label for="fruit">Fruit</label> <select id="fruit" name="fruit"> <option value="">Choose one…</option> <optgroup label="Citrus"> <option value="orange">Orange</option> <option value="lime">Lime</option> </optgroup> <optgroup label="Berries"> <option value="fig" selected>Fig</option> </optgroup> </select> ``` ## Where the submitted value comes from An option's value is its `value` attribute if the attribute is present, and otherwise the option's text content (whitespace stripped and collapsed). Both of these are legal: ```html <option value="gb">United Kingdom</option> <option>United Kingdom</option> ``` The first sends `gb`; the second sends `United Kingdom`. Relying on text content is fragile — a copy edit or a translation silently changes the value your server receives — so give every option an explicit `value` unless the visible text *is* the data. There is a third, separate attribute: `label` on an `<option>` overrides the text the browser displays. It changes presentation, not the submitted value. A `disabled` option cannot be chosen at all, so it never contributes a value. `disabled` on an `<optgroup>` disables all of its options at once. ## Which option starts selected Mark one option `selected`. That attribute is the *initial* state, which is also what a form reset restores; the current selection afterwards lives in the DOM, not in the attribute. If you mark none, a dropdown (no `multiple`, no `size` above 1) still has a selection — the browser selects the first option in document order that is not disabled. This surprises people who expect an "empty" select. It is why the placeholder pattern is written as a genuine first option: ```html <select name="plan" required> <option value="" selected disabled>Choose a plan…</option> <option value="free">Free</option> <option value="pro">Pro</option> </select> ``` The empty `value` is what makes that placeholder distinguishable from a real answer on the server, and it is also what a `required` select treats as "nothing chosen". Note that `<select value="pro">` does nothing. There is no `value` content attribute on `<select>`; only the DOM property `select.value` exists, and setting it selects the option whose value matches. ## Grouping, size, and multiple `<optgroup>` needs its `label` attribute — that string is the group heading, it is not selectable, and assistive technology announces it as the group a focused option belongs to. Groups do not nest; an `<optgroup>` inside an `<optgroup>` is invalid and browsers will not render nested levels. `size` sets how many rows are visible. `size="1"` (the default for a plain select) is the familiar dropdown; a larger `size` renders a scrolling list box that is always expanded. `multiple` turns the control into a multi-select list box, rendered with several visible rows even without `size`. Two consequences matter. First, selection requires modifier-clicking or shift-clicking on desktop, which many users never discover — a group of checkboxes is usually the kinder control. Second, each selected option contributes its own entry under the same `name`, and a multi-select with nothing selected contributes nothing at all, so server code must handle both "a list" and "absent". ## The bugs that actually ship - Options with no `value` whose text later changes, silently changing the data. - A placeholder written as text on the select instead of a first `<option>`, so there is no way to represent "not answered". - Assuming an untouched dropdown submits nothing — it submits its first non-disabled option. - Reaching for a styled `<div>` list because the native dropdown is hard to style. You lose keyboard type-ahead, mobile's native picker, and form participation; if the design truly demands it, that is a full combobox implementation, not a styling exercise.

  • What is the difference between the selected attribute in the markup and the DOM's select.value after a user interacts?
    The `selected` attribute is the default state: it decides the initial selection and is what a form reset restores. Once the page is live, the current selection is DOM state — the attribute does not follow the user's clicks. Setting `select.value` in script picks the matching option but likewise leaves the markup attribute untouched, so serialising the DOM back to HTML would lose the user's choice.
  • A designer wants users to pick several tags. Would you use <select multiple> or a checkbox group, and why?
    Usually a checkbox group. `<select multiple>` works, but selecting more than one item requires Ctrl/Cmd-click or shift-click, which is undiscoverable, awkward on touch, and easy to destroy accidentally with a stray click. Checkboxes make every option and its state visible, each has its own label and hit target, and they submit the same repeated `name` pairs. Reserve `multiple` for long lists where vertical space is genuinely scarce.
  • How would you build a select whose options are grouped and where a whole group can be turned off temporarily?
    Wrap each group in `<optgroup label="…">` and put `disabled` on the group you want turned off. A disabled `<optgroup>` disables all of its options, so none of them can be chosen or submitted, while the heading still renders and communicates that the group exists but is unavailable. It is one attribute rather than looping over the child options.

saying these in an interview costs you the question

  • Writing value on the <select> tag to preselect an option
  • Assuming an option always submits its visible text
  • Thinking an untouched dropdown submits nothing
  • Nesting optgroup elements to build sub-groups
  • Believing a disabled option still contributes a value

context