Text inputs cover free-form answers. For choices, longer text and grouped questions, HTML has dedicated controls. Each one has its own rules for names, values and defaults, and each works with the keyboard and assistive technology without extra code.
textarea: multi-line text
<label for="message">Your message</label>
<textarea id="message" name="message" rows="5" maxlength="1000"></textarea>
rowssets the visible height in lines;colssets the width in characters, though CSSwidthis more common.- The default value goes between the tags, not in a
valueattribute. - Whitespace between the tags is part of the value, so keep the opening and closing tags together when the field should start empty.
<!-- Starts with a line break and spaces as its value -->
<textarea name="notes">
</textarea>
<!-- Starts empty -->
<textarea name="notes"></textarea>
select: choose from a list
<label for="loaf">Loaf</label>
<select id="loaf" name="loaf">
<option value="">Choose a loaf</option>
<option value="white">White tin</option>
<option value="sourdough" selected>Sourdough</option>
<option value="rye">Seeded rye</option>
</select>
- Each
optionhas avalue, which is sent, and text, which is shown. If you leave outvalue, the text is sent. selectedsets the default option. Without it, the first option is selected.- An empty-value first option such as "Choose a loaf" works with
required: the browser treats an empty value as no choice.
Group long lists with optgroup:
<label for="class">Class</label>
<select id="class" name="class">
<optgroup label="Bread">
<option value="sourdough">Sourdough basics</option>
<option value="rye">Rye and wholegrain</option>
</optgroup>
<optgroup label="Pastry">
<option value="croissant">Croissants</option>
</optgroup>
</select>
multiple turns a select into a list where several options can be chosen. It is awkward to use, since people must hold Ctrl or Cmd to pick more than one. A group of checkboxes is usually clearer.
For long lists that people would rather type into, such as countries, input with a datalist gives suggestions while still allowing free text. A select with fewer than about five options is often better as radio buttons, because people can see every choice at once.
Checkboxes
A checkbox is an independent on or off choice:
<input type="checkbox" id="newsletter" name="newsletter" value="yes">
<label for="newsletter">Send me the monthly newsletter</label>
When checked, the browser sends newsletter=yes. When unchecked, it sends nothing at all for that name. Your server must treat a missing field as "no". Without a value, a checked box sends on.
checked sets the default. Do not pre-tick boxes for marketing consent; in many places, including under UK and EU data protection law, consent must be an active choice.
Checkbox groups
For "choose any that apply" questions, give several checkboxes the same name. Each checked box sends its own pair, such as diet=vegan&diet=nut-free.
Radio buttons
Radio buttons are a set where only one can be chosen. They form a group by sharing the same name:
<input type="radio" id="collect" name="delivery" value="collect" checked>
<label for="collect">Collect from the shop</label>
<input type="radio" id="local" name="delivery" value="local">
<label for="local">Local delivery (£3)</label>
- Choosing one deselects the others in the same group.
- Keyboard users Tab into the group once, then use the arrow keys to move between options.
- Once a radio in a group is chosen, it cannot be unchosen by clicking it again. If "none" is a valid answer, add it as an option.
fieldset and legend: grouping controls
When several controls answer one question, wrap them in fieldset and give the question in legend, which must be the first child:
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Order details</title>
</head>
<body>
<h1>Order details</h1>
<form action="/order" method="post">
<fieldset>
<legend>How would you like to receive your order?</legend>
<div>
<input type="radio" id="collect" name="delivery" value="collect" required>
<label for="collect">Collect from the shop</label>
</div>
<div>
<input type="radio" id="local" name="delivery" value="local">
<label for="local">Local delivery (£3)</label>
</div>
</fieldset>
<fieldset>
<legend>Dietary requirements (choose any that apply)</legend>
<div>
<input type="checkbox" id="vegan" name="diet" value="vegan">
<label for="vegan">Vegan</label>
</div>
<div>
<input type="checkbox" id="nut-free" name="diet" value="nut-free">
<label for="nut-free">Nut-free</label>
</div>
</fieldset>
<p>
<label for="notes">Anything else we should know?</label>
<textarea id="notes" name="notes" rows="4"></textarea>
</p>
<button type="submit">Place order</button>
</form>
</body>
</html>
Without the fieldset, a screen reader user hearing "Vegan, checkbox, not checked" does not know what the question was. With it, screen readers announce the legend when focus enters the group. Sighted users get a visible question and a border, which you can restyle with CSS.
required on one radio in a group makes the whole group required. Checkbox groups have no built-in "choose at least one" rule; that needs your own validation.
Use fieldset for:
- radio button groups, always,
- checkbox groups,
- related fields such as the parts of an address or a date split into day, month and year.
Do not wrap every single field in its own fieldset; it adds noise.
disabled on a fieldset disables every control inside it in one go. It is handy for sections that only apply after another choice, such as a delivery address that is needed only for delivery.
Hidden inputs
<input type="hidden" name="class-id" value="42"> sends a value that people do not see or edit, such as an identifier. It is not secret: anyone can read and change it in DevTools, so never trust it on the server.
Default values at a glance
| Control | How to set the default |
|---|---|
Text-like input | value="..." |
textarea | Text between the tags |
select | selected on an option |
| Checkbox and radio | checked |
The reset button, and the reset() method in JavaScript, return controls to these defaults.
Summary
textareaholds multi-line text; its default value goes between the tags.selectlists options; group them withoptgroupand set defaults withselected.- Checkboxes are independent and send nothing when unchecked. Radios share a
nameand allow one choice. - Wrap groups of related controls in
fieldsetwith alegendthat asks the question. - Hidden inputs are visible to anyone who looks; treat them as untrusted.