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.
select and textarea: Two Inputs With Surprising Rules
These two form controls behave differently from a normal <input>, and each has a gotcha worth knowing.
<select name="country">
<option value="">Choose…</option>
<option value="bd" selected>Bangladesh</option> <!-- default choice -->
<optgroup label="Asia">
<option value="jp">Japan</option>
</optgroup>
</select>
<textarea name="bio" rows="4">Initial text goes BETWEEN the tags</textarea>
The <textarea> trap: unlike <input>, its value goes between the tags, not in a value attribute. <textarea value="hi"> does nothing. And whitespace/newlines inside the tags are preserved literally, so don't indent the content.
| Element | Key attribute |
|---|---|
<option selected> | pre-selected choice |
<select multiple> | allow several selections |
<optgroup> | group options under a label |
Details: the submitted value is each option's value attribute (falls back to its text if omitted), so always set meaningful values. For <select>, a first empty "Choose…" option paired with required forces a real choice. Size a <textarea> with CSS (height) rather than rows for responsive layouts, and use resize: vertical to control dragging.
🏋️ Practical Exercise
- Create a
<select>dropdown with three<option>s. - Pre-select one option with the
selectedattribute. - Group options with
<optgroup>. - Allow multiple selections with the
multipleattribute. - Add a
<textarea>withrowsandcols.
🔥 Challenge Exercise
Build a feedback form with a <select> for category (grouped with <optgroup>), a multi-select list of topics, and a <textarea> for comments with a placeholder. Associate a label with each. Explain when a <select> is a better choice than radio buttons.
📋 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.
Interview Questions
- How do you create a dropdown menu in HTML?
- What does the
selectedattribute do on an<option>? - How do you allow multiple selections in a
<select>? - What is
<optgroup>used for? - How do
rowsandcolsdiffer from sizing a<textarea>with CSS?
Related Topics
FAQ
<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.
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).
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.
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.

