HTML select, textarea, fieldset and legend Explained
Learn the HTML select dropdown with optgroup, the textarea for multi-line text, and how fieldset and legend group related form fields properly.
What you will learn
Not every form field is a single-line <input>. In this lesson you will learn <select> for dropdown menus (including grouping options with <optgroup>), <textarea> for multi-line text, and <fieldset>/<legend>, which group related fields together — a small addition with a real accessibility payoff that most beginner tutorials skip entirely.
<select>: a dropdown menu
<label for="country">Country</label>
<select id="country" name="country">
<option value="in">India</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
</select>
<select>is the dropdown itself, connected to a<label>exactly like an<input>(for/id).- Each
<option>is one choice in the list. - The
namegoes on<select>(not on the individual options), and thevaluesubmitted is whichever option’svalueattribute the visitor picked.
value vs. the visible text
This trips up beginners: the text between <option> and </option> is what the visitor sees, but the value attribute is what actually gets submitted. They don’t have to match:
<select name="country">
<option value="in">India 🇮🇳</option>
<option value="us">United States 🇺🇸</option>
</select>
If a visitor picks “India 🇮🇳”, the form submits country=in, not the emoji-decorated display text. If you leave out value entirely, the option’s own text content is used as the value instead — but it’s better practice to always set value explicitly, especially when the visible label might change later (translations, formatting) and you don’t want that to silently change the submitted data too.
selected: pre-choosing an option
<select name="country">
<option value="in" selected>India</option>
<option value="us">United States</option>
</select>
Without a selected option, the browser defaults to showing the first <option> in the list — which can be misleading if that first option isn’t actually a sensible default. It’s good practice to either explicitly mark a sensible default with selected, or add a genuine placeholder option:
<select name="country" required>
<option value="" disabled selected>Choose your country</option>
<option value="in">India</option>
<option value="us">United States</option>
</select>
Here, disabled stops the placeholder itself from being a choosable option, and required (covered properly in the next lesson) stops the form from submitting if the visitor never picks a real one.
multiple: selecting more than one option
<select name="skills" multiple size="4">
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="js">JavaScript</option>
<option value="python">Python</option>
</select>
With multiple, the visitor can select several options at once (usually by Ctrl/Cmd-clicking, or by touch on mobile). size sets how many options are visible at once without scrolling — without it, a multiple select tends to render awkwardly small.
<optgroup>: organising a long list
When a dropdown has many options, group related ones under a labelled heading with <optgroup>:
<select name="country">
<optgroup label="South Asia">
<option value="in">India</option>
<option value="pk">Pakistan</option>
<option value="bd">Bangladesh</option>
</optgroup>
<optgroup label="Europe">
<option value="uk">United Kingdom</option>
<option value="de">Germany</option>
</optgroup>
</select>
<optgroup>’s label is shown as a bold, unselectable heading inside the dropdown — purely visual/organisational, and it never gets submitted itself. Only the <option> elements inside it can actually be chosen.
<textarea>: multi-line text
<label for="message">Your message</label>
<textarea id="message" name="message" rows="5" cols="40"></textarea>
Unlike <input>, <textarea> is not a void element — it has a closing tag, and its starting content goes between the tags, not in a value attribute:
<!-- Right: starting text goes between the tags -->
<textarea name="bio">Tell us about yourself...</textarea>
<!-- Wrong: value does nothing here -->
<textarea name="bio" value="Tell us about yourself..."></textarea>
If you want faint hint text that disappears on typing (rather than real starting content the visitor has to delete), use
placeholderinstead, exactly like on<input>:<textarea name="bio" placeholder="Tell us about yourself..."></textarea>
Sizing a textarea
rows— how many lines tall it starts.cols— roughly how many characters wide it starts.maxlength— the maximum number of characters the visitor can type.
<textarea name="feedback" rows="4" cols="50" maxlength="500" placeholder="Up to 500 characters"></textarea>
In practice, most real sites control the exact width with CSS (width: 100%) rather than relying on cols, since cols is a rough character-count estimate that varies with font. rows remains useful as a starting height. By default, a <textarea> can also be resized by the visitor by dragging its bottom-right corner — you can control this with the CSS resize property (resize: vertical, resize: none, and so on) when you reach the CSS course.
<fieldset> and <legend>: grouping related fields
This pair is easy to skip as a beginner, but it does real, visible work for accessibility. <fieldset> draws a box around a group of related fields, and <legend> gives that group a caption.
<form>
<fieldset>
<legend>Contact preferences</legend>
<label><input type="radio" name="contact" value="email" checked> Email</label>
<label><input type="radio" name="contact" value="phone"> Phone</label>
</fieldset>
<fieldset>
<legend>Delivery address</legend>
<label for="street">Street</label>
<input type="text" id="street" name="street">
<label for="city">City</label>
<input type="text" id="city" name="city">
</fieldset>
</form>
Why bother? A <label> describes one field. When a screen reader user tabs into a lone radio button labelled just “Email”, they have no idea it’s part of a “Contact preferences” choice unless something announces that group context — <legend> is exactly that announcement. It’s especially valuable for radio button groups and checkbox groups, where each individual option’s label alone doesn’t explain what they’re choosing between.
<legend> must be the first element inside its <fieldset>, and each <fieldset> should have exactly one.
disabled on a whole fieldset
A handy bonus: setting disabled on a <fieldset> disables every field inside it at once, which is useful for something like greying out a shipping-address section until the visitor checks “ship to a different address”:
<fieldset disabled>
<legend>Shipping address (currently same as billing)</legend>
<input type="text" name="shipStreet">
<input type="text" name="shipCity">
</fieldset>
Putting it together
<form>
<fieldset>
<legend>Your Details</legend>
<label for="country">Country</label>
<select id="country" name="country">
<option value="" disabled selected>Choose your country</option>
<optgroup label="South Asia">
<option value="in">India</option>
<option value="pk">Pakistan</option>
</optgroup>
<optgroup label="Other">
<option value="us">United States</option>
</optgroup>
</select>
<label for="bio">A little about you</label>
<textarea id="bio" name="bio" rows="4" maxlength="300" placeholder="Optional"></textarea>
</fieldset>
</form>
Common mistakes
- Assuming the
<option>text is what gets submitted. It’s thevalueattribute — always set it explicitly. - Putting starting text in a
valueattribute on<textarea>. It has no effect; write the starting text between the opening and closing tags, or useplaceholderfor hint text instead. - Using
multipleon<select>without settingsize, resulting in an unusably small, cramped list. - Skipping
<fieldset>/<legend>on grouped radio buttons or checkboxes, leaving screen reader users without the context of what the group of options actually represents. - Putting
<legend>anywhere except as the very first child of<fieldset>. - Nesting a
<fieldset>where it isn’t really a distinct group, adding a visual box with no real organisational benefit.
Interview-style questions
What is the difference between an <option>’s visible text and its value?
The text between the tags is what the visitor sees in the dropdown; the value attribute is what actually gets submitted with the form — they don’t have to be the same.
Why doesn’t a value attribute work on <textarea>?
<textarea> is not a void element — its starting content goes between the opening and closing tags, not in a value attribute, which <textarea> doesn’t use at all.
What problem does <fieldset>/<legend> solve?
A <label> only describes one field, so when several related fields form a group (like a set of radio buttons), <legend> provides the group-level context that a screen reader announces alongside each individual field’s own label.
Practice
-
Use the Practice in Editor button. Change the
selectedoption in the country dropdown and check that a different country is shown by default. -
Add a second
<optgroup>with two more countries of your choice. -
Add
maxlength="100"to the textarea and try typing past that limit. -
Fix this code (it has two mistakes: a
valueused on<textarea>, and a<legend>placed after other content in the<fieldset>):<fieldset> <label for="notes">Notes</label> <textarea id="notes" name="notes" value="Type here..."></textarea> <legend>Additional Notes</legend> </fieldset>
Recap
<select>+<option>builds a dropdown; the submitted data is each option’svalue, not necessarily its visible text.selectedpre-chooses an option;multiple(withsize) allows choosing several;<optgroup>organises a long list under labelled headings.<textarea>takes its starting content between its tags, not in avalueattribute;rows,colsandmaxlengthcontrol its size and limit.<fieldset>groups related fields visually and semantically, and<legend>(its required first child) gives that group a caption — essential context for grouped radio buttons and checkboxes.disabledon a whole<fieldset>disables every field inside it at once.