Checkboxes, Radios & Pickers
Checkboxes let users pick any combination of options independently. Radio buttons enforce exactly one choice per named group. Both need a fieldset and legend when the group has a shared question that gives the choices their meaning.
What it is
<input type="checkbox"> creates an independent toggle. Each checkbox in a form has its own checked state and each contributes a separate entry to the submission when checked. Multiple checkboxes can share a name attribute, which causes the submission to include one name=value pair per checked box. A checkbox that is not checked contributes nothing at all: the server cannot distinguish "user did not check it" from "user never saw it" without a hidden field carrying a default.
<input type="radio"> works differently: radios are grouped by their name attribute, and the browser enforces that only one per group is checked at a time. Selecting a radio automatically unchecks every other radio with the same name, regardless of where they are in the DOM. Unlike checkboxes, a radio group can have at most one value in the submission. The value attribute on each radio is what gets sent when that option is selected; if value is omitted the browser submits the literal string "on".
Why it matters
Choosing the wrong control sends the wrong signal to the user. When only one answer is valid ("which plan do you want?"), radio buttons make the mutual exclusion visible and enforce it natively. Using checkboxes for a single-answer question lets the user check multiple boxes and submit an invalid combination that your server then has to reject. The control type is part of the interface contract.
The <fieldset> and <legend> pattern matters for radio groups in particular. A screen reader navigating to a radio button for "Medium" has no way to know the question is "What size?" unless there is a programmatic group label. <legend> provides that label and is announced before each radio in the group when AT reads the options. Removing the fieldset leaves users with a list of options and no question.
How it works
For a checkbox group, give each <input type="checkbox"> a unique id (for its label) and the same name as its siblings. Set value to the string you want the server to receive for that option. Each checked box contributes name=value to the submission independently. Unchecked boxes contribute nothing.
For a radio group, give every <input type="radio"> the same name. This is what links them: changing one unchecks the others with the same name, wherever they live in the document. Set a distinct value on each. Use checked on one radio to set the default selection; a radio group without a default forces the user to make a choice before any value is selected, which is sometimes intentional but requires careful validation.
Picker inputs follow the same label and name rules as text inputs. <input type="date"> opens a calendar picker in supporting browsers and submits a value in YYYY-MM-DD format regardless of how the picker displays the date locally. <input type="color"> submits a lowercase hex string like #ff5500. <input type="range"> submits its numeric value; pair it with an <output> element to display the current value.
Try it
Toggle between checkbox and radio modes. Check options and watch the submission preview update to show exactly what the server would receive.
<fieldset> <legend>Topics</legend> <input type="checkbox" name="topic" id="js" value="javascript" /> <label for="js">JavaScript</label> <input type="checkbox" name="topic" id="css" value="css" /> <label for="css">CSS</label></fieldset><!-- any combo submits --><!-- unchecked = omitted -->
Control type
fieldset / legend: Topicsany combination
fieldset / legend: Sizename="size" groups them
Submission
topic=javascript
name=value pair. Unchecked boxes are absent from the submission entirely.Check yourself
Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.
Remember this
- Checkbox: any combination of options can be checked; each checked box submits its own
name=valuepair. - Radio: only one per
namegroup can be checked; grouping is bynameattribute, not by DOM nesting. - Always set
valueon radios: omitting it submits the useless string "on". - Wrap radio groups in
<fieldset>+<legend>so screen readers announce the group question before each option.
Done with this concept?
Mark it complete to track your progress. No login needed.