๐ŸŽ›๏ธ Chapter 23: Selection & Choice Inputs

Radio Buttons with type="radio"

Mutually exclusive selection architecture, WAI-ARIA radio group mechanics, and keyboard roving focus navigation.

LEARNING OBJECTIVES โŒต
  • Understand the architectural design and mutual exclusivity model of <input type="radio">.
  • Master the keyboard accessibility mechanics of radio groups, including roving focus via arrow keys.
  • Implement semantic grouping using <fieldset> and <legend> for assistive technologies.
  • Manage initial default states and avoid the "un-uncheckable" trap in required radio groups.
๐ŸŽฌ INTERACTIVE VISUAL PIPELINE Core Architecture Simulation
๐ŸŒ
1. Input
Directives & Tags
โš™๏ธ
2. Parse
Tokenizer & AST
๐ŸŒณ
3. Layout
Box Model & Flow
๐ŸŽจ
4. Render
GPU Paint & Composite
PHASE 1: INPUT & DIRECTIVES
Browser receives declarative markup stream, parsing tag tokens and initializing component state.

๐Ÿ“– The Mental Model & Story (Intuitive Foundation)

Imagine driving a vintage 1970s automobile equipped with an analog push-button car radio on the dashboard.

+-------------------------------------------------------------+
|                     CAR STEREO DASHBOARD                    |
|                                                             |
|   [ AM 540 ]   [ AM 720 ]   [ FM 89.9 ]   [ FM 98.1 ]       |
|      ( )          ( )          (*)           ( )            |
|                                 ^                           |
|                        Currently Depressed                  |
+-------------------------------------------------------------+

Inside that physical stereo was a mechanical latch bar. When you pressed the button for FM 89.9, the mechanical bar snapped that button down and simultaneously popped out whichever preset station had been pressed before. You could never listen to two radio stations at the exact same momentโ€”the physics of the mechanical latch made choices strictly mutually exclusive.

This mechanical car radio is the exact namesake for HTML's <input type="radio">.

When you present users with a question where exactly one answer must be chosen from a small list of options (e.g., shipping speed, billing frequency, gender marker, payment gateway), radio buttons are the gold standard UI pattern.


Technical Deep Dive & Specifications

Mutual Exclusivity Mechanics

In the WHATWG HTML standard, radio buttons are bound together by sharing the exact same name attribute within their form owner.

+-------------------------------------------------------------------------------+
|                         RADIO GROUP STATE TRANSITION                          |
+-------------------------------------------------------------------------------+

  Initial State (name="shipping"):
    Option A (Standard Ground):  [ checked = true  ]  (*)
    Option B (Priority Air):     [ checked = false ]  ( )
    Option C (Overnight):        [ checked = false ]  ( )

  User Clicks Option C:
    Browser Engine:
      1. Finds all <input type="radio"> sharing name="shipping" in current form.
      2. Iterates over group: sets Option A.checked = false, Option B.checked = false.
      3. Sets Option C.checked = true.
      4. Dispatches 'change' event on Option C (and Option A loses selection).

  Payload Serialized: "shipping=overnight" (Only 1 pair submitted!)

Keyboard Navigation & Roving Focus

Radio buttons implement a specialized keyboard navigation model known in accessibility specifications as the Roving Tabindex Pattern:

Keyboard Interaction Architecture:
  User presses [ Tab ]:
    -> Focus moves directly into the radio group.
    -> If an option is checked, focus lands ON the checked option.
    -> If NO option is checked, focus lands on the FIRST radio option.

  User presses [ Arrow Down ] or [ Arrow Right ]:
    -> Focus AND selection immediately shift to the NEXT radio button.
    -> The newly focused radio is automatically checked.

  User presses [ Arrow Up ] or [ Arrow Left ]:
    -> Focus AND selection immediately shift to the PREVIOUS radio button.
    -> Cycles from top to bottom (wraps around).

  User presses [ Tab ] again:
    -> Focus LEAVES the radio group entirely and moves to the NEXT form control.
Key / Gesture WAI-ARIA Standard Action
Tab Enters the group (focusing the selected option) or exits the group.
Down Arrow / Right Arrow Selects and focuses the next radio button in the group (cycles to first if on last).
Up Arrow / Left Arrow Selects and focuses the previous radio button in the group (cycles to last if on first).
Space Selects the currently focused radio button if none was selected.

The Semantic Structure: <fieldset> and <legend>

Because individual radio buttons only have short labels (e.g., "Standard ($5.00)"), screen reader users tabbing directly into the field would not know the context of the question without a grouping container.

The W3C Accessibility Guidelines (WCAG 2.1 SC 1.3.1 & SC 3.3.2) require grouping related radio buttons using <fieldset> with an explicit <legend>:

<fieldset>
  <!-- The legend acts as the accessible question title for screen readers -->
  <legend>Choose Delivery Speed</legend>

  <div>
    <input type="radio" id="ship-std" name="shipping_method" value="ground" checked>
    <label for="ship-std">Standard Ground (3โ€“5 Business Days)</label>
  </div>
  <div>
    <input type="radio" id="ship-exp" name="shipping_method" value="express">
    <label for="ship-exp">Express Air (2 Business Days)</label>
  </div>
</fieldset>

When a screen reader focuses ship-exp, it reads: "Choose Delivery Speed, Express Air, radio button, checked, 2 of 2".

The "Un-uncheckable" Quirk & Initial Defaults

Unlike checkboxes (which can be toggled on and off repeatedly), a radio button cannot be unchecked by clicking it a second time. Once an option is chosen, the user can only change their choice to a different radio button in the same group.

Checkbox: Click [X] -> Click [ ] -> Click [X]  (Toggleable)
Radio:    Click (*) -> Click (*) -> (*)         (Permanent once selected)

[!IMPORTANT] Always provide an explicit checked attribute on the most common, sensible default option in your radio group. If you do not provide a default and the user clicks any option by mistake, they cannot revert to an empty state without resetting the entire form.


SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
HTML STARSHIP CODE TERMINAL example.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45ยฐC
INSPECTING DOM: VALID
TAGS: SCANNING...

๐Ÿ’ป Interactive Code Playground

Starter Code

Line-by-Line Code Breakdown

  • Lines 50โ€“52 (<fieldset> & <legend>): Groups the mutually exclusive controls into a cohesive semantic unit and defines the accessible group title.
  • Lines 55โ€“68 (Option 1): Defines the default active selection with checked. Both the input and label are linked using for="ship-standard" and id="ship-standard".
  • Lines 70โ€“96 (Options 2 & 3): Options sharing name="shipping_tier". Clicking or using arrow keys to select either option will automatically deactivate Option 1.
  • Submission Payload: When submitted with Priority Air selected, the HTTP POST body contains strictly: shipping_tier=priority.

Expected Browser Render Output


SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
HTML STARSHIP CODE TERMINAL playground.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45ยฐC
INSPECTING DOM: VALID
TAGS: SCANNING...
+-----------------------------------------------------------+
| Select Shipping Method                                    |
|                                                           |
| +-------------------------------------------------------+ |
| | (*) Standard Delivery โ€” $4.99                         | |
| |     Estimated delivery in 4โ€“6 business days           | |
| +-------------------------------------------------------+ |
| +-------------------------------------------------------+ |
| | ( ) Priority Air โ€” $12.99                             | |
| |     Guaranteed delivery in 2 business days            | |
| +-------------------------------------------------------+ |
| +-------------------------------------------------------+ |
| | ( ) Overnight Priority โ€” $24.99                       | |
| |     Next business day delivery by 10:30 AM            | |
| +-------------------------------------------------------+ |
|                                                           |
| [ Continue to Payment ]                                   |
+-----------------------------------------------------------+

๐Ÿ‹๏ธ Hands-On Exercise

๐ŸŽฏ The Challenge: Build an Accessible Subscription Plan Selector

Instructions:

  1. Construct an accessible subscription plan selector inside a <form> using semantic <fieldset> and <legend> tags.
  2. The legend should read: "Choose Your Subscription Plan".
  3. Create three distinct radio options sharing name="subscription_plan":
    • Starter Tier: value="starter", price $9/mo, single user.
    • Professional Tier: value="pro", price $29/mo, up to 10 users (pre-selected by default using checked).
    • Enterprise Tier: value="enterprise", price $99/mo, unlimited users.
  4. Add a required attribute to the radio group to guarantee form validation.
  5. Provide accessible <label> markup so users can click anywhere on the plan description to trigger selection.

๐Ÿ Starter Code Sandbox

SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
STARTER CODE SANDBOX exercise.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45ยฐC
INSPECTING DOM: VALID
TAGS: SCANNING...

โš ๏ธ Common Pitfalls

  1. Using Checkboxes for Mutually Exclusive Questions: Using <input type="checkbox"> for questions like "Select Gender" or "Select Shipping Speed" is a serious UX flaw because users can check multiple boxes, creating contradictory data.
  2. Forgetting <fieldset> and <legend>: Placing bare radio buttons without a <fieldset> makes it impossible for screen reader users to understand what category the radio buttons belong to when cycling with arrow keys.
  3. Different name Attributes on Same Group: If you write name="plan1", name="plan2", and name="plan3", the browser considers each input an independent group, breaking mutual exclusivity completely.

๐Ÿ’ก Pro Tips

  1. Modern CSS :has() for Interactive Cards: Use .card:has(input[type="radio"]:checked) to style entire surrounding containers without writing JavaScript click listeners.
  2. Arrow Key Navigation Testing: Always verify your radio buttons using pure keyboard navigation. Tabbing should enter the group once, arrow keys should cycle selections, and tabbing again should leave the group.

๐Ÿ“Œ Key Takeaways

  • <input type="radio"> controls enforce mutually exclusive selection where only one option can be chosen at a time.
  • All radio buttons participating in the same selection group must share the exact same name attribute.
  • Keyboard navigation uses the Roving Focus Pattern: Tab enters/leaves the group, while Arrow Keys change selection.
  • Radio groups should always be wrapped in a semantic <fieldset> with an explanatory <legend>.
  • Unlike checkboxes, once a radio button is selected, it cannot be deselected by clicking it again; it can only be switched to another radio.
  • --
โญ LEARN: HTML ๐ŸŒŸ โš”๏ธ QUIZ BATTLE ARENA // ACTIVE
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 1 / 3

How does a screen reader user navigate between different radio buttons within the same group?

Question 1 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 2 / 3

What happens if none of the radio buttons in a group have a checked attribute when the page loads?

Question 2 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 3 / 3

Which semantic HTML tags should wrap a group of related radio buttons to ensure optimal accessibility?

Question 3 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP