Form controls in depth: select, textarea, checkboxes, radios and fieldset

Every common form control, how to group related controls, and how default values work.

  • Beginner
  • 6 min read
  • Updated 17 Oct 2026

What you will learn

  • Group related controls with fieldset
  • Build radio and checkbox groups
  • Set default values for every control type

Before you start

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

HTML
<label for="message">Your message</label>
<textarea id="message" name="message" rows="5" maxlength="1000"></textarea>
  • rows sets the visible height in lines; cols sets the width in characters, though CSS width is more common.
  • The default value goes between the tags, not in a value attribute.
  • Whitespace between the tags is part of the value, so keep the opening and closing tags together when the field should start empty.
HTML
<!-- 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

HTML
<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 option has a value, which is sent, and text, which is shown. If you leave out value, the text is sent.
  • selected sets 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:

HTML
<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:

HTML
<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:

HTML
<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:

HTML
<!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

ControlHow to set the default
Text-like inputvalue="..."
textareaText between the tags
selectselected on an option
Checkbox and radiochecked

The reset button, and the reset() method in JavaScript, return controls to these defaults.

Summary

  • textarea holds multi-line text; its default value goes between the tags.
  • select lists options; group them with optgroup and set defaults with selected.
  • Checkboxes are independent and send nothing when unchecked. Radios share a name and allow one choice.
  • Wrap groups of related controls in fieldset with a legend that asks the question.
  • Hidden inputs are visible to anyone who looks; treat them as untrusted.

Further reading