multiple

Allows multiple values in a single form control. Behaves completely differently on select, email input, and file input.

Overview

The multiple attribute allows a form control to accept more than one value. It applies to three elements, but the behavior is completely different in each case. This is one attribute with three distinct meanings depending on context.

ElementBehaviorHow Values Are Sent
<select multiple>Multi-select listboxMultiple entries with the same name
<input type="email" multiple>Comma-separated emailsSingle comma-separated string
<input type="file" multiple>Multi-file pickerMultiple file entries with the same name

Select: Multi-Select Listbox

Adding multiple to a <select> transforms the dropdown into an always-visible listbox. Users select multiple options with Ctrl+click (Windows/Linux) or Cmd+click (macOS). Holding Shift selects a range.

<label for="languages">Languages you speak</label> <select id="languages" name="languages" multiple size="5"> <option value="en">English</option> <option value="es">Spanish</option> <option value="fr">French</option> <option value="de">German</option> <option value="ja">Japanese</option> <option value="zh">Chinese</option> <option value="pt">Portuguese</option> </select>

Use the size attribute to control how many options are visible. Without size, most browsers default to showing 4 options.

/* Size the multi-select to show several options */ select[multiple] { min-height: 8rem; padding: 0.25rem; } /* Style individual options */ select[multiple] option { padding: 0.375rem 0.5rem; border-radius: 0.25rem; } select[multiple] option:checked { background: var(--color-primary); color: var(--color-text-on-primary); } const select = document.querySelector('#languages'); // Get all selected values const selected = Array.from(select.selectedOptions) .map(opt => opt.value); // → ["en", "fr"] // Check if a specific value is selected const speaksSpanish = select.querySelector('option[value="es"]').selected;

Usability warning: Multi-select listboxes have notoriously poor discoverability. Many users do not know about Ctrl+click, and accidentally clicking without Ctrl deselects everything. For more than a handful of options, consider a group of checkboxes instead.

Email Input: Comma-Separated Addresses

On <input type="email">, the multiple attribute allows the user to enter multiple email addresses separated by commas. The browser validates each address independently.

<label for="recipients">Recipients</label> <input type="email" id="recipients" name="recipients" multiple placeholder="jane@example.com, john@example.com" /> const input = document.querySelector('#recipients'); // The value is a comma-separated string console.log(input.value); // → "jane@example.com, john@example.com" // The browser validates EACH email independently // Invalid: "jane@example.com, not-an-email" → fails validation

This is useful for "To" fields in email-like UIs or invitation forms where multiple recipients are expected.

File Input: Multi-File Upload

On <input type="file">, the multiple attribute lets the user select more than one file from the file picker dialog. Without it, only one file can be selected at a time.

<label for="photos">Upload Photos</label> <input type="file" id="photos" name="photos" multiple accept="image/*" /> const input = document.querySelector('#photos'); input.addEventListener('change', () => { // input.files is a FileList (array-like) for (const file of input.files) { console.log(file.name, file.size, file.type); } console.log(`${input.files.length} files selected`); });

Pair multiple with the accept attribute to filter the file picker by type. The user can still select files outside the filter, so always validate on the server.

Form Data Differences

Each element type sends its values differently in FormData. This matters for server-side processing.

const form = document.querySelector('form'); form.addEventListener('submit', (e) => { e.preventDefault(); const data = new FormData(form); // Multi-select: multiple entries with the same key const languages = data.getAll('languages'); // → ["en", "fr", "ja"] // Email multiple: single comma-separated string const recipients = data.get('recipients'); // → "jane@example.com, john@example.com" // File multiple: multiple File objects with the same key const photos = data.getAll('photos'); // → [File, File, File] });

For <select multiple> and <input type="file" multiple>, use getAll() instead of get() to retrieve all values. Using get() returns only the first value.

Accessibility

  • <select multiple> is announced as a "listbox" by screen readers. Selected options are announced as "selected". Users can navigate with arrow keys and toggle selection with Space.
  • For multi-select, provide instructions near the field explaining how to select multiple options (e.g., "Hold Ctrl/Cmd to select multiple"). Keyboard users need to know about Ctrl+Space.
  • Multi-file inputs are generally well-supported by assistive technology. The file dialog handles multi-selection natively.

Limitations

  • multiple only works on <select>, <input type="email">, and <input type="file">. It has no effect on other input types.
  • <select multiple> cannot be styled as a dropdown. It always renders as a listbox. There is no way to have a dropdown that allows multiple selections with native HTML alone.
  • The required attribute on <select multiple> means at least one option must be selected, but there is no native way to require a minimum number of selections.
  • Multi-file inputs reset completely when the user opens the file picker again. Previously selected files are replaced, not appended. Accumulating files across multiple picker interactions requires JavaScript.
  • multiple is a boolean attribute. multiple="false" still enables multiple selection. Remove the attribute to disable it.

See Also

  • list — connect inputs to suggestion datalists
  • required — require at least one selection
  • <select> element reference
  • <input> element reference