Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
Allows multiple values in a single form control. Behaves completely differently on select, email input, and file input.
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.
| Element | Behavior | How Values Are Sent |
|---|---|---|
<select multiple> | Multi-select listbox | Multiple entries with the same name |
<input type="email" multiple> | Comma-separated emails | Single comma-separated string |
<input type="file" multiple> | Multi-file picker | Multiple file entries with the same name |
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 valuesconst selected = Array.from(select.selectedOptions) .map(opt => opt.value);// → ["en", "fr"] // Check if a specific value is selectedconst 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.
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="[email protected], [email protected]" />
const input = document.querySelector('#recipients'); // The value is a comma-separated stringconsole.log(input.value);// → "[email protected], [email protected]" // The browser validates EACH email independently// Invalid: "[email protected], not-an-email" → fails validation/code-block <p>This is useful for "To" fields in email-like UIs or invitation forms where multiple recipients are expected.</p> <h2>File Input: Multi-File Upload</h2><p>On <code><input type="file"></code>, the <code>multiple</code> 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.</p> <code-block language="html" label="Multiple file upload" data-escape><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.
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'); // → "[email protected], [email protected]" // 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.
<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.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.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.multiple is a boolean attribute. multiple="false" still enables multiple selection. Remove the attribute to disable it.