Skip to content

Radio Group

Radio groups collect mutually exclusive options under one prompt. Use them when several radios answer the same question and need shared context, description, or validation.

Component

Use fd-radio-group to wrap related fd-radio options in a native <fieldset> with a shared <legend>. The group handles vertical or horizontal layout, optional description and error text, and the "select one" validation pattern.

When to use

  • Several radios answer one prompt — Preferred contact method, delivery channel, account type, statement frequency, and similar single-choice decisions.
  • The options need shared help text — Group-level description reduces repetition when the same clarification applies to every option.
  • One selection is required — Use group-level validation when the rule is "choose exactly one."

When not to use

  • Don't use a group for a single radio — A single option with no alternatives is not a meaningful radio group.
  • Don't use a group when users may select more than one option — That is a checkbox-group pattern.
  • Don't rely on horizontal layout for dense lists — Horizontal groups are only appropriate for short, low-count option sets.
  • 6 or more options in a non-critical context — Use fd-selector with variant="single" when the list is long enough that visible radios would dominate the page. However, for highly consequential selections (regulatory, financial, irreversible), prefer radio groups regardless of count because visible options reduce the risk of accidental selection.

Examples

Radio group overview — vertical layout, long-label wrapping, disabled options, and required group messaging. Open Storybook for form validation and horizontal layout examples. View in Storybook →

Properties

NameTypeDefaultDescription
orientation"vertical" | "horizontal"verticalLayout direction for the radio set
requiredbooleanfalseRequires one enabled radio to be selected
disabledbooleanfalseDisables the group and temporarily disables enabled child radios
labelstring``Fallback legend text when no legend slot content is provided

Slots

NameDescription
legendOptional replacement for the authored legend text
descriptionGroup-level help text announced from the fieldset
(default)One or more fd-radio children
errorGroup-level validation message shown and announced while invalid

Events

NameDetailDescription
fd-radio-group-change{ value: string }Fired when the selected radio changes

Compatibility note:

  • fd-radio-group still fires deprecated fd-group-change with { selectedValue: string } during the compatibility window.
  • New consumer code should listen to fd-radio-group-change.

CSS custom properties

NameDefaultDescription
--fd-radio-group-max-width32remMaximum inline size of the group
--fd-radio-group-legend-gapvar(--fdic-spacing-xs, 8px)Space between the legend and the description or items
--fd-radio-group-description-gapvar(--fdic-spacing-sm, 12px)Space below the description before the radio items
--fd-radio-group-gapvar(--fdic-spacing-sm, 12px)Gap between radio items

Shadow parts

NameDescription
fieldsetNative fieldset wrapper
legendNative legend element
descriptionGroup-level description wrapper
itemsContainer for slotted fd-radio children
errorGroup-level error message wrapper

Best practices

Do

Write the legend as a full prompt

The legend should make sense before the user reads any individual option labels.

Don't

Use the legend as a vague heading

Generic headings make the user scan every option just to understand the question.

Do

Include "(required)" in the legend text

Making the requirement visible in the legend avoids relying on color or symbols alone.

Don't

Use required without providing an error message

Provide an error slot whenever the group is required so screen reader users hear the validation message inline. Without it, only the browser's native validation tooltip is available.

Content guidelines

  • Use plain-language legends.
  • Place required text in the legend. Example: "Preferred contact method (required)".
  • Provide one group-level error message. The error belongs to the group, not to individual radios.
  • When the choice affects legal notices or regulated content, explain the consequence of each option in the description — not just the mechanics.

Accessibility

  • fd-radio-group renders a real native <fieldset> and <legend> in Shadow DOM.
  • Group-level aria-describedby is computed. Description text is referenced only when present, and error text is referenced only when present and the group is invalid.
  • The group participates in validation through ElementInternals, but submits no form value of its own. Individual fd-radio children submit their own name / value pairs.
  • Arrow-key navigation between radios is coordinated by fd-radio. Disabled radios are skipped during arrow movement.
  • checkValidity() updates and returns validity without revealing invalid state.
  • reportValidity(), form submit attempts, and focus leaving the logical group after user interaction reveal invalid state when the group is invalid. The host gets data-user-invalid and the internal <fieldset> gets aria-invalid="true".
  • aria-invalid is present iff data-user-invalid is present, and it clears in the same update cycle when the group becomes valid or when the form reset path runs.
  • Provide one authored group-level error message in the error slot whenever the group can block submission. Missing error copy is incomplete usage even though invalid styling still appears.

Known limitations

  • Native radio group tab-stop behavior is not fully reproducible across separate shadow roots — Arrow-key navigation is coordinated by fd-radio, but Tab behavior depends on the browser's treatment of shadow-separated inputs. Manual AT verification (NVDA, JAWS, VoiceOver) is required before release.
  • Group container structure is derived from fd-checkbox-group, not from a distinct radio-group Figma comp — The individual radio anatomy is Figma-backed; group chrome follows the checkbox-group pattern for consistency.
  • Dynamic child disabled toggles while the group is disabled are out of scope in v1 — Set child-specific disabled states before disabling the group or after re-enabling it.
  • Automatic name propagation is deferred — Consumers must set name on each fd-radio child. The group warns at dev time if names are empty or mismatched.