Command Palette

Search for a command to run...

Hectal
PHASE 4Intermediate ~19 min· topic 4 of 8

Topic 4.4

Checkboxes, Radio Buttons and Selects

In one line

Checkboxes let people pick any number of options, radio buttons sharing a name let them pick exactly one, <select> packs choices into a drop-down (or a list with multiple), and <datalist> suggests values for a free-text box.

Think of it like this

A pizza order. Toppings are checkboxes: tick none, one or all of them. Size is radio buttons: small, medium or large, and picking one un-picks the others, like the preset buttons on an old car radio (which is where the name comes from). Your city is a drop-down menu: a long list folded up so it doesn't fill the page.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

Checkbox
A small box that can be ticked or not. Any number of them can be ticked.
Radio button
A round option where only one in its group can be picked.
Radio group
Radio buttons that share the same name. Picking one un-picks the others.
checked
The attribute that makes a checkbox or radio start ticked. .checked is the live state in JavaScript.
select
A drop-down list of choices. Each choice is an <option>.
optgroup
A heading that groups options inside a select. It can't be picked itself.
multiple
An attribute that lets a select (or email/file input) take more than one value.
datalist
A list of suggestions shown under a text box. The person can still type anything.

Step by step

01Checkboxes: pick any

Each checkbox is independent. Shared name, different values. The labels wrap the boxes so the words are clickable.

index.htmlwhole filehtml
<fieldset>
  <legend>Toppings</legend>
  <label><input type="checkbox" name="topping" value="cheese" checked> Cheese</label>
  <label><input type="checkbox" name="topping" value="olives"> Olives</label>
</fieldset>

02Radio buttons: pick one

The shared name="size" is what makes these a group. Give them different names by mistake and they become separate, and all three can be on at once.

index.htmlwhole filehtml
<fieldset>
  <legend>Size</legend>
  <label><input type="radio" name="size" value="s"> Small</label>
  <label><input type="radio" name="size" value="m" checked> Medium</label>
  <label><input type="radio" name="size" value="l"> Large</label>
</fieldset>

03What each kind sends

Only ticked boxes and the picked radio are sent. A missing name in the data means "not ticked"; your server code must treat "missing" as "no".

What each kind sendsdiagram
Rendering diagram…

04A drop-down with groups

optgroup adds headings. The empty-value first option makes "nothing chosen yet" possible.

index.htmlwhole filehtml
<label for="city">City</label>
<select id="city" name="city" required>
  <option value="">Choose a city</option>
  <optgroup label="India">
    <option value="pune">Pune</option>
    <option value="blr">Bengaluru</option>
  </optgroup>
</select>

05Suggestions with datalist

The input's list points at the datalist's id. Suggestions show as you type; the value is whatever ends up in the box.

index.htmlwhole filehtml
<label for="fruit">Favourite fruit</label>
<input id="fruit" name="fruit" list="fruits">
<datalist id="fruits">
  <option value="Apple"></option>
  <option value="Mango"></option>
</datalist>

Try it yourself

  1. 1

    Untick everything

    In the first example, remove every checked attribute and the .click() line. Predict the first line of output, then run it. (An empty line: nothing is sent when nothing is ticked.)

  2. 2

    Split the group

    Rename the Large radio to name="size2". In the preview, pick Medium, then Large. Both stay on: they're no longer one group.

  3. 3

    Use the keyboard

    In the preview, click Small, then press the arrow keys. The selection moves through the group. Press Tab: focus leaves the whole group in one step.

  4. 4

    Type a value that isn't suggested

    In the second example, type Guava into the fruit box and run console.log(form.elements.fruit.value) from the JS tab. A datalist only suggests; it doesn't restrict.

Code & diagrams

Checkboxes and a radio group New tab

Clicking Large un-picked Medium. The agree box has no `value`, so it sends `on`. Olives isn't ticked, so it isn't sent at all.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

topping=cheese&topping=corn&size=m&terms=on
topping=cheese&topping=corn&size=l&terms=on
Medium still checked? false
All toppings: [ 'cheese', 'corn' ]
Selects, optgroups, multiple and a datalist New tab

`selectedIndex` counts options across all optgroups: the placeholder is 0, Pune 1, Bengaluru 2, Tokyo 3.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

city: blr index 2
now: Tokyo (no value attribute, so the text is used)
langs: [ 'html', 'js' ]
langs .value gives only the first: html
fruit: Mango | suggestions: 3

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Radio buttons with different names

Give each size radio its own name: name="small", name="medium", name="large".

terminal
$ the page shows
── what you'll see ──
Small, Medium and Large can all be selected at once, and none can be unselected

Break #2

Expect an unticked checkbox to send false

On the server, read terms and treat a missing value as an error.

terminal
$ Form data
── what you'll see ──
topping=cheese&size=m (no terms pair at all)

Myth vs fact

Myth

An unchecked checkbox sends false.

Fact

It sends nothing. Missing means unchecked.

Myth

Radio buttons need JavaScript to un-pick the others.

Fact

The browser does it for any radios sharing a name in the same form.

Myth

A datalist limits what can be typed.

Fact

It only offers suggestions. Use a <select> (or validation) to allow only listed values.

Myth

A select's value is always the option's text.

Fact

The value attribute is sent when present; the text is used only when there's no value.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Checkboxes have a third visual state, indeterminate (a dash, meaning "some of the items below are ticked"). It can only be set from JavaScript (box.indeterminate = true), is not submitted, and is matched by the :indeterminate CSS pseudo-class.

  • ▸

    A radio group is scoped to its form owner plus name: radios with the same name in different forms are separate groups. A required attribute on any radio in the group makes the whole group required.

  • ▸

    select.value returns only the first selected option. Read every choice with [...select.selectedOptions].map(o => o.value) or formData.getAll(name).

  • ▸

    Styling native selects has long been limited. Chromium added customizable select (appearance: base-select with ::picker(select)) in 2025; it isn't Baseline yet, so treat it as an enhancement and keep the default look working.

Remember this

  1. 1

    A checkbox is <input type="checkbox">. Each one is on or off. Give it a value: when ticked, it sends name=value; when not ticked it sends nothing at all, not false. A checkbox with no value sends on. Several checkboxes may share one name (like topping); the server then receives the name several times (topping=cheese&topping=corn).

  2. 2

    A radio button is <input type="radio">. Radio buttons with the **same name form a group**: checking one unchecks the rest, and the group sends one pair, like size=m. If nobody picks one, the group sends nothing. Keyboard users press Tab to move into the group and the arrow keys to move between options. Always put a radio group in a <fieldset> with a <legend> that asks the question (Topic 4.3).

  3. 3

    The checked attribute sets which boxes start ticked, just as value sets a text box's starting text. In JavaScript, the .checked property is the live state (true or false). Give a radio group a sensible default only when one choice is really the usual one; otherwise people may submit a choice they never made.

  4. 4

    A select is the <select> element with <option> elements inside. Each option's value is what gets sent; if an option has no value, its text is sent. selected sets the starting choice; otherwise the first option is chosen. A first option like <option value="">Choose a city</option> plus required forces a real choice (Topic 4.7). <optgroup label="..."> groups options under a heading that can't itself be picked.

  5. 5

    Adding multiple turns the drop-down into a list box where several options can be selected (Ctrl/Cmd-click on a computer). Each selected option is sent as its own pair, like checkboxes. Multiple selects are awkward to use, especially on desktop, so for a few options a group of checkboxes is usually friendlier.

  6. 6

    A datalist is a list of suggestions for a normal input: <input list="fruits"> + <datalist id="fruits"><option value="Mango"></datalist>. As the person types, matching suggestions appear, but they can still type anything else. Use <select> when only the listed answers are allowed and <datalist> when the list is just a helpful shortcut.

Explain it without notes

01

When should you use checkboxes, radio buttons, a select or a datalist?

02

What is sent for a checked checkbox with no value, and for an unchecked one?

03

How does the browser know which radio buttons belong together?

04

How do you read all selected options of a <select multiple>?

Practice

01

Write a question "How did you hear about us?" with radio buttons Friend, Search engine and Social media, in a fieldset.

02

Write a country select with optgroups Asia (India, Japan) and Europe (France, Spain) and a first option that forces a choice.

Trade-offs

  • ↔

    Radio buttons show every option at once (fast to scan, one click) but take space; a select saves space but hides the options behind an extra click and is harder to scan.

  • ↔

    A <select multiple> is compact but hard to use (modifier-key clicks, easy to lose selections); a checkbox group is clearer but longer.

Done when you can

  • I can build a checkbox group and a radio group with a fieldset and legend.

  • I know what a checked and an unchecked checkbox send.

  • I can build a select with optgroups, a placeholder option and selected.

  • I can read several selected values with getAll.

  • I can add a datalist and explain how it differs from a select.