HTML The select Dropdown

The <select> element creates a dropdown list that lets users pick one value (or several) from a predefined set of choices. It’s the standard way to offer a constrained list of options in an HTML form — think country pickers, size selectors, or status filters — without forcing the user to type free text that then needs validation.

Unlike text inputs, a <select> guarantees the submitted value always comes from a fixed list you control, which makes server-side validation simpler and the user experience faster since they just pick rather than type.

Overview / How it works

A <select> element is a form control that wraps one or more <option> elements. Each <option> represents one choice in the list. When the form is submitted, the browser sends the name of the <select> paired with the value of whichever <option>(s) were selected — not the visible text, unless no value attribute is given, in which case the option’s text content is used as the fallback value.

In the DOM, <select> is a replaced, form-associated element. Browsers render it using the operating system’s native widget in most cases: on desktop, clicking it typically opens a native dropdown list rendered outside the normal page layout (often as a popup layer), while on mobile it usually opens a full-screen or sheet-style picker. This is why <select> looks different across Windows, macOS, iOS, and Android — the browser defers to the platform’s UI for the open list, even though the closed control itself is styled somewhat by the browser/CSS.

Because the rendering of the open dropdown is largely outside CSS’s reach, <select> trades visual customization for consistency, accessibility, and correct keyboard behavior (arrow keys to move, typing a letter to jump to a matching option, Escape to close) for free — behavior you would have to reimplement by hand with a custom widget.

A <select> can behave in two modes:

  • Single-select dropdown — the default; only one option can be chosen, and the closed control shows a compact box with the current selection.
  • Multi-select list box — enabled by adding the multiple attribute; the browser instead renders an inline scrollable list (no popup), and the user can select several options at once, usually by Ctrl/Cmd-clicking or Shift-clicking.

Syntax

<select name="NAME" id="ID">
  <option value="VALUE_1">Label 1</option>
  <option value="VALUE_2" selected>Label 2</option>
  <option value="VALUE_3">Label 3</option>
</select>
Attribute Applies to Description
name select The key used when the selected value is submitted with the form.
id select Used to associate a <label for="..."> with this control.
multiple select Boolean attribute; allows more than one option to be selected at once.
size select Number of visible rows; when greater than 1, renders as an inline list box instead of a popup.
required select Boolean attribute; form submission is blocked unless a non-empty value is chosen.
disabled select or option Prevents interaction; a disabled option cannot be chosen, a disabled select isn’t submitted at all.
value option The data sent to the server if this option is chosen. Falls back to the option’s text if omitted.
selected option Boolean attribute; marks this option as chosen by default when the page loads.
label optgroup The heading text shown above a group of related options.

Examples

Example 1: A basic single-select dropdown

<form>
  <label for="country">Country:</label>
  <select name="country" id="country">
    <option value="">-- Choose a country --</option>
    <option value="us">United States</option>
    <option value="ca">Canada</option>
    <option value="mx">Mexico</option>
  </select>
</form>

Result: A label reading “Country:” appears next to a closed dropdown box showing “– Choose a country –“. Clicking it opens a list of four options; picking “Canada” closes the list and displays “Canada” in the box. If submitted without changing the selection, country= (empty) is sent, since the placeholder option has an empty value.

This pattern — a first option with an empty value acting as a placeholder — is the standard way to force a deliberate choice, especially when combined with required.

Example 2: A pre-selected default and grouped options

<form>
  <label for="pet">Favorite pet:</label>
  <select name="pet" id="pet">
    <optgroup label="Mammals">
      <option value="dog" selected>Dog</option>
      <option value="cat">Cat</option>
      <option value="rabbit">Rabbit</option>
    </optgroup>
    <optgroup label="Birds">
      <option value="parrot">Parrot</option>
      <option value="canary">Canary</option>
    </optgroup>
  </select>
</form>

Result: The closed box shows “Dog” by default because of the selected attribute. Opening it reveals two visually separated, non-clickable group headings, “Mammals” and “Birds”, each followed by their own indented, selectable options.

<optgroup> is purely organizational: its label is displayed but can never itself be selected or submitted, only the <option> elements inside it can.

Example 3: A multi-select list box

<form>
  <label for="toppings">Choose toppings (Ctrl/Cmd-click for multiple):</label>
  <select name="toppings" id="toppings" multiple size="4">
    <option value="cheese">Cheese</option>
    <option value="pepperoni">Pepperoni</option>
    <option value="mushroom">Mushroom</option>
    <option value="olive">Olive</option>
    <option value="onion">Onion</option>
  </select>
</form>

Result: Because multiple is present, the browser renders an inline scrollable box (not a popup) showing 4 rows at a time out of the 5 total options, with “Onion” reachable by scrolling. Ctrl-clicking (or Cmd-clicking on Mac) “Cheese” and then “Olive” highlights both. On submission, the form data includes two separate toppings=cheese and toppings=olive pairs, since a multi-select sends one entry per chosen option under the same name.

How it works step by step

  • The parser encounters <select> and creates an HTMLSelectElement node in the DOM, along with an internal list of associated options.
  • Each child <option> (optionally nested inside an <optgroup>) becomes an HTMLOptionElement, exposing .value, .text, and .selected properties.
  • If no <option> has the selected attribute, the browser automatically treats the first option in source order as selected — there is always a selected option in a single-select box.
  • When the user opens the control, the browser paints the option list using native OS UI rather than the page’s normal layout flow, which is why it can visually overflow the viewport or appear as a separate layer.
  • Choosing an option updates select.value immediately and fires a change event, closing the popup for single-select controls.
  • On form submission, the browser walks each <select>‘s selected option(s) and encodes them as name=value pairs, repeating the name once per selected option when multiple is set.

Common Mistakes

Mistake 1: Forgetting a value attribute and expecting the visible label to always be what’s submitted.

<select name="size">
  <option>Small (S)</option>
  <option>Medium (M)</option>
</select>

This isn’t invalid, but it’s fragile: without value, the submitted data is the exact visible text, including any extra wording like “(S)”. If a designer later tweaks the label text, the submitted value silently changes too, potentially breaking server-side logic that matches on it.

<select name="size">
  <option value="S">Small</option>
  <option value="M">Medium</option>
</select>

Now the submitted value (S or M) is stable and decoupled from the display label.

Mistake 2: Nesting elements other than option/optgroup directly, or leaving tags unclosed.

<select name="color">
  <option value="red">Red
  <option value="blue">Blue</option>
</select>

Leaving out closing </option> tags is technically tolerated by lenient HTML parsers (the next <option> implicitly closes the previous one), but it’s easy to introduce subtle bugs and it fails stricter validators. Always close every <option> explicitly:

<select name="color">
  <option value="red">Red</option>
  <option value="blue">Blue</option>
</select>

Mistake 3: Marking two options as selected in a single-select box. In a plain <select> (no multiple), only the last selected option in source order actually wins — browsers silently ignore the earlier ones, which can confuse anyone reading the markup later. Only add selected to more than one <option> when multiple is also present on the <select>.

Best Practices

  • Always pair <select> with a <label for="..."> matching its id, so screen readers and clicking the label both work correctly.
  • Give every meaningful <option> an explicit value, even when it matches the visible text, so the submitted data is stable and intentional.
  • Use a disabled, empty-value first option (e.g. “– Select one –“) together with required to force a real choice rather than silently defaulting to the first real option.
  • Use <optgroup> to organize long lists (10+ options) into logical categories instead of one flat list.
  • Reserve multiple for cases where selecting several values genuinely makes sense to the user; it changes both the rendering and the submitted data shape.
  • Don’t rely on styling the open dropdown list with CSS — its appearance is largely controlled by the operating system, not your stylesheet.

Practice Exercises

  • Build a <select> named language with options for “English”, “Spanish”, and “French”, using two-letter values (en, es, fr), with “English” selected by default.
  • Create a multi-select box named days listing the seven days of the week, with size="5", and predict how many days=... pairs would be submitted if a user selected three days.
  • Take a flat list of 8 country options and reorganize it into two <optgroup> sections, “North America” and “Europe”, keeping each option’s value unchanged.

Summary

  • The <select> element creates a dropdown (or list box) built from <option> children.
  • The submitted data is each option’s value, not its visible text, unless value is omitted.
  • Without selected, the first option is chosen by default; with multiple, several options can be selected and each is submitted separately under the same name.
  • <optgroup> visually and semantically groups related options but is never itself selectable.
  • The open dropdown list is rendered by the operating system, so its appearance can’t be fully controlled with CSS.
  • Always associate a <label> with a <select> for accessibility and usability.