HTMLDropdowns (<select>, <option>, <optgroup>)

Dropdowns (<select>, <option>, <optgroup>)

<select> renders a dropdown control for choosing from a predefined list of options, each represented by an <option>. It's the standard way to offer a closed set of choices without listing every one as a separate radio button.

Basic Dropdown

basic-select.html

HTML
<label for="country">Country</label>
<select id="country" name="country">
  <option value="us">United States</option>
  <option value="ca">Canada</option>
  <option value="mx">Mexico</option>
</select>
value vs Display Text

Each <option> has two pieces of text that can differ: the value attribute, which is what actually gets submitted with the form, and the text between the opening and closing tags, which is what the user sees in the dropdown. If value is omitted, the browser submits the visible text instead.

value-vs-text.html

HTML
<select name="country">
  <!-- Submitted value is "us", displayed text is "United States" -->
  <option value="us">United States</option>

  <!-- No value attribute — the displayed text "Canada" is submitted as-is -->
  <option>Canada</option>
</select>
Always set an explicit value when it matters
Relying on the displayed text as the submitted value is fragile — if you later rename "United States" to "USA" for display purposes, the submitted value silently changes too, potentially breaking server-side logic that expected the old string.
selected — Preselecting an Option

Add the boolean selected attribute to an <option> to make it the initial choice when the page loads. Without it, the browser defaults to the first <option> in the list.

selected-option.html

HTML
<select name="shipping-speed">
  <option value="standard">Standard (5-7 days)</option>
  <option value="express" selected>Express (2-3 days)</option>
  <option value="overnight">Overnight</option>
</select>
optgroup — Grouping Related Options

<optgroup> visually and semantically groups related options under a shared, non-selectable label — useful when a long list naturally breaks into categories.

optgroup.html

HTML
<label for="dish">Choose a dish</label>
<select id="dish" name="dish">
  <optgroup label="Appetizers">
    <option value="soup">Soup of the Day</option>
    <option value="salad">Caesar Salad</option>
  </optgroup>
  <optgroup label="Main Courses">
    <option value="salmon">Grilled Salmon</option>
    <option value="pasta">Wild Mushroom Pasta</option>
  </optgroup>
</select>

Element

Role

<select>

The dropdown container and form control

<option>

One selectable choice inside the dropdown

<optgroup>

A non-selectable visual/semantic grouping label for related options

The multiple Attribute: Multi-Select Listbox

Adding multiple to <select> changes it from a closed dropdown into a scrollable listbox where several options can be selected at once (typically with Ctrl/Cmd-click or Shift-click). Submitted data becomes multiple values under the same field name.

multi-select.html

HTML
<label for="skills">Skills (select all that apply)</label>
<select id="skills" name="skills" multiple size="4">
  <option value="html">HTML</option>
  <option value="css">CSS</option>
  <option value="js">JavaScript</option>
  <option value="ts">TypeScript</option>
</select>
Multi-select UX is not always obvious to users
Many users don't realize they need to hold Ctrl/Cmd to select multiple options in a listbox, since it isn't visually indicated. If the multi-select interaction is important, consider checkboxes instead, or pair the listbox with a short instruction like "Hold Ctrl (Cmd on Mac) to select multiple."

The size attribute (used above) controls how many rows are visible at once. Without multiple, size can still be set greater than 1 to show a scrollable list instead of a closed dropdown, even for single selection.

Always associate a <label>
Just like other form controls, connect a <label> via for/id (or wrap the select in the label) so screen readers announce a meaningful name for the dropdown.
  • Use <select>/<option> for choosing from a fixed, closed set of values.

  • The submitted value comes from value if present, otherwise the visible option text.

  • Use selected to preselect an option; without it, the first option is chosen by default.

  • Use <optgroup> to visually and semantically group related options under a label.

  • Add multiple to allow selecting more than one option as a scrollable listbox.

A Disabled Placeholder Option

A common pattern shows a non-selectable placeholder like "Select an option" as the initial state, implemented with a disabled, selected, often value-less first <option>.

placeholder-option.html

HTML
<label for="country">Country</label>
<select id="country" name="country" required>
  <option value="" disabled selected>Select a country&hellip;</option>
  <option value="us">United States</option>
  <option value="ca">Canada</option>
  <option value="mx">Mexico</option>
</select>
Pair with required for validation
Because the placeholder option's value is empty, adding required on the <select> prevents form submission until the user actually picks a real option.
Disabling Individual Options

Any single <option> can be disabled independently, greying it out and preventing it from being selected, while the rest of the dropdown remains usable — useful for showing out-of-stock items or unavailable time slots without hiding them entirely.

disabled-option.html

HTML
<label for="size">Size</label>
<select id="size" name="size">
  <option value="s">Small</option>
  <option value="m">Medium</option>
  <option value="l" disabled>Large (out of stock)</option>
</select>
Reading and Setting Values in JavaScript

select-js.js

JS
const select = document.getElementById('country');

console.log(select.value); // the currently selected option's value

select.addEventListener('change', () => {
  console.log('New selection:', select.value);
});

// Setting the value programmatically selects the matching <option>
select.value = 'ca';

For a multiple select, reading all selected values requires iterating over the selectedOptions collection instead of relying on the single value property.

multi-select-js.js

JS
const skillsSelect = document.getElementById('skills');

const selectedSkills = [...skillsSelect.selectedOptions].map((opt) => opt.value);
console.log(selectedSkills); // e.g. ["html", "ts"]
select vs Radio Buttons vs Checkboxes

Control

Best for

Downside

<select>

Long lists of options where showing all at once would take too much space

Hides all options behind a click; harder to scan quickly

Radio buttons

Short lists (2–5) where seeing every option at a glance helps

Takes up more vertical space for long lists

Checkboxes

Multi-select from a short, fully visible list

Not appropriate for single-choice selection

For short lists, consider radio buttons instead
Hiding 3 options behind a dropdown often adds an unnecessary click and hides choices a user might have picked at a glance. Dropdowns earn their keep once a list gets long enough that showing every option directly would clutter the page.