The select Element
The <select> element creates a dropdown menu. It acts as a container for <option> elements, each representing one choice. Like all form controls, it needs a name attribute to be included in form submission, and a <label> for accessibility.
<label for="country">Country</label>
<select id="country" name="country">
<option value="gb">United Kingdom</option>
<option value="us">United States</option>
<option value="ca">Canada</option>
<option value="au">Australia</option>
</select>
When submitted, the form sends the name paired with the value of the selected <option>. If an option has no value attribute, the browser sends the option's visible text content as the value.
The option Element
Each <option> represents one item in the dropdown. Key attributes:
value— the data sent to the server when this option is selected (often a short code or ID).selected— pre-selects this option when the page loads.disabled— makes this option unselectable (used for placeholder options).
<label for="language">Preferred language</label>
<select id="language" name="language">
<!-- Placeholder option: disabled + no value, selected by default -->
<option value="" disabled selected>Choose a language…</option>
<!-- Regular options with short value codes -->
<option value="en">English</option>
<option value="fr">Français</option>
<option value="de">Deutsch</option>
<option value="es">Español</option>
<!-- Pre-selected option -->
<option value="pt" selected>Português</option>
</select>
<option value="" disabled selected>Choose…</option> creates a "Choose a value" prompt that users cannot reselect once they pick a real option. If you also add required to the <select>, the browser will reject submission if the empty-value placeholder is still selected.
optgroup – Grouping Options
When a dropdown has many options, <optgroup> organises them into labelled groups with a visual separator. The label attribute on <optgroup> is the group heading — it is not selectable itself.
<label for="course-pick">Select a course</label>
<select id="course-pick" name="course">
<optgroup label="Web Development">
<option value="html-101">HTML Fundamentals</option>
<option value="css-101">CSS Basics</option>
<option value="js-101">JavaScript Essentials</option>
</optgroup>
<optgroup label="Programming">
<option value="python-101">Python for Beginners</option>
<option value="c-101">C Programming</option>
<option value="cpp-101">C++ Foundations</option>
</optgroup>
<optgroup label="Data Science">
<option value="sql-101">SQL Fundamentals</option>
<option value="pandas-101">Pandas & NumPy</option>
</optgroup>
</select>
Multiple Selection
Adding the multiple attribute to <select> turns the dropdown into a scrollable list box where users can select more than one option (Ctrl+click or Shift+click on desktop). The size attribute controls how many rows are visible.
<label for="skills">Select your skills (hold Ctrl to choose multiple)</label>
<select id="skills" name="skills" multiple size="5">
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="js">JavaScript</option>
<option value="python">Python</option>
<option value="sql">SQL</option>
<option value="git">Git</option>
</select>
When multiple options are selected, the browser submits the name multiple times, once for each selected value. Server-side code must handle this as an array. Use name="skills[]" in PHP or similar array notation depending on your server framework.
The textarea Element
The <textarea> element creates a multi-line text input. Unlike <input>, it has a visible opening and closing tag. Its initial content goes between the tags (not in a value attribute).
<label for="feedback">Your feedback</label>
<textarea id="feedback" name="feedback"
rows="6" cols="50"
placeholder="Tell us what you think…"
maxlength="1000"></textarea>
<!-- Pre-filled textarea (content between tags) -->
<label for="edit-bio">Bio</label>
<textarea id="edit-bio" name="bio" rows="4">I am a web developer based in London.</textarea>
rows— sets the visible height in lines of text (approximate; varies by font).cols— sets the visible width in average character widths (approximate). Usually better to control width with CSS.placeholder— hint text shown when the textarea is empty.maxlength— hard limit on character count.
Controlling textarea Resize
By default, most browsers allow users to drag the resize handle on textareas. You can control this with CSS.
/* Allow only vertical resize (most common: prevents breaking layout) */
textarea {
resize: vertical;
}
/* No resize at all */
textarea.fixed {
resize: none;
}
/* Full resize (default browser behaviour) */
textarea.resizable {
resize: both;
}
/* Sensible defaults for textarea layout */
textarea {
width: 100%;
max-width: 600px;
min-height: 120px;
padding: 0.75rem;
border: 1px solid #ced4da;
border-radius: 4px;
font-family: inherit;
font-size: 1rem;
line-height: 1.5;
resize: vertical;
}
Styling select Elements
Native <select> dropdowns are notoriously difficult to style consistently across browsers. Browsers render the dropdown list (the popup) using OS-native controls, which CSS cannot fully reach. Basic styles like background colour, border, padding, and font can be applied to the select box itself.
select {
appearance: none; /* remove default OS arrow */
-webkit-appearance: none;
background-color: #fff;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23666' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 0.75rem center;
background-size: 12px;
padding: 0.5rem 2.5rem 0.5rem 0.75rem;
border: 1px solid #ced4da;
border-radius: 4px;
font-size: 1rem;
cursor: pointer;
width: 100%;
max-width: 300px;
}
<select> or a div-based widget with role="listbox" and full ARIA attributes. Libraries like Select2 and Choices.js are popular options.
📋 Summary
<select>creates a dropdown; always pair with a<label>and give it anameattribute.<option value="">— each choice;valueis what gets submitted;selectedpre-selects it.<optgroup label="">— groups options under a non-selectable heading.multipleon<select>— allows selecting several options; avoid on mobile, prefer checkboxes.<textarea rows="" cols="">— multi-line text input; initial content goes between the tags.- Control textarea resize with CSS
resize: vertical(recommended) orresize: none. - Native select styling is limited; use
appearance: nonewith a custom SVG arrow for consistent cross-browser appearance.
Frequently Asked Questions
Why does my select have no placeholder like input does?
<select> does not support the placeholder attribute. The common workaround is a disabled, selected option with an empty value: <option value="" disabled selected>Choose…</option>. Pair it with required on the select so the form cannot be submitted with that placeholder still selected.
How do I get the selected value from a select in JavaScript?
Access selectElement.value for the value of the currently selected option. For a multiple select, iterate over selectElement.selectedOptions — it returns an HTMLCollection of all selected option elements: [...select.selectedOptions].map(opt => opt.value).
Why does whitespace matter in textarea?
Unlike other HTML elements, whitespace between <textarea> tags is preserved and becomes the initial content. If you write <textarea>\n </textarea> with a newline and spaces, those appear as initial content. Always write <textarea></textarea> with no space between tags for an empty default value.
Can I add images or icons inside option elements?
No. The <option> element only renders plain text — no HTML, no images. To create dropdown menus with icons or rich content, you need a fully custom JavaScript component built with divs, ARIA roles (role="combobox", role="listbox", role="option"), and keyboard event handling.