v1.6.x-dev NDS IQ v6

Radio Button - National Design System

Single-selection input controls for mutually exclusive options with clear visual feedback

Radio Button Group

Mutually exclusive options with shared validation and required state

Select your plan
<fieldset class="nds-form-group nds-radio-group" data-required> <legend class="nds-label">Select your plan</legend> <div class="nds-form-container nds-radio-container"> <div class="nds-form-header"> <label for="radio1"> <span class="nds-label">Basic</span> <span class="nds-info">Core features for individuals</span> </label> </div> <div class="nds-form-control"> <input type="radio" id="radio1" name="plan" value="basic" class="nds-radio"> </div> </div> <div class="nds-form-container nds-radio-container"> <div class="nds-form-header"> <label for="radio2"> <span class="nds-label">Professional</span> <span class="nds-info">Advanced tools for teams</span> </label> </div> <div class="nds-form-control"> <input type="radio" id="radio2" name="plan" value="pro" class="nds-radio"> </div> </div> <div class="nds-form-container nds-radio-container"> <div class="nds-form-header"> <label for="radio3"> <span class="nds-label">Enterprise</span> <span class="nds-info">Full access with dedicated support</span> </label> </div> <div class="nds-form-control"> <input type="radio" id="radio3" name="plan" value="enterprise" class="nds-radio"> </div> </div> <div class="nds-form-footer" data-feedback-target hidden></div> </fieldset>

Readonly State

Freezes the border color without disabling interaction or graying the tile fill

Preferred contact
<div class="nds-form-container nds-radio-container" data-state="readonly"> <div class="nds-form-header"> <label for="radio-readonly1"> <span class="nds-label">Email</span> <span class="nds-info">Receive updates by email</span> </label> </div> <div class="nds-form-control"> <input type="radio" id="radio-readonly1" name="contact" value="email" class="nds-radio" checked> </div> </div>

Built-in Features

What you get out of the box with zero configuration

Form Integration

Auto-initializes with the forms system. Two-way binding syncs disabled and required states between inputs and containers.

Group Validation

Required selection enforced on form submit. Auto-revalidates on change once an error is shown. Call NDS.Forms.clearStatus() to reset.

Visual Feedback

Ripple effect on hover, smooth state transitions, and three sizes (SM, MD, LG) with proportional scaling.

Responsive Layout

Column layout by default, row layout with nds-rowView class. Gaps adjust on mobile for touch-friendly spacing.

Usage Guidelines

When and how to use radio buttons effectively

When to Use

  • Selecting exactly one option from a mutually exclusive set
  • Use checkboxes when multiple selections are allowed
  • Use a select dropdown when there are more than 7 options
  • Use switches for instant on/off actions without form submission
  • Always provide a default selection when possible to avoid empty submissions
  • Wrap options in a fieldset with a legend that describes what the user is choosing

JavaScript API

// Validate a radio group manually var group = document.querySelector('.nds-radio-group'); var result = NDS.Forms.validateRadioGroup(group); // result: { valid: false, selected: false, message: 'Please select an option' } // Validate without showing feedback NDS.Forms.validateRadioGroup(group, { showMessage: false }); // Set status manually (error, success, warning, info) NDS.Forms.setStatus({ element: group, status: 'error', message: 'Please select an option' }); // Clear validation status NDS.Forms.clearStatus(group); // Re-sync chrome after a programmatic .checked assignment // (updates sibling radio containers and the clear button; no event re-dispatch) var radio = document.querySelector('#radio1'); radio.checked = true; NDS.Forms.syncState(radio);

Modifier Classes

ClassTargetDescription
nds-neutral.nds-radioNeutral color variant for the checked tile fill
nds-md.nds-radio-containerMedium size: increases tile and gap proportionally, widens gap ring to 4 px
nds-lg.nds-radio-containerLarge size: further increases tile and gap proportionally, widens gap ring to 5 px
nds-rowView.nds-radio-groupArranges radio options horizontally in a row instead of the default column

Data Attributes

AttributeTargetDescription
data-required.nds-radio-groupMarks the group as required; a selection is enforced on form submit
data-error-message.nds-radio-groupOverrides the default validation error message shown when no option is selected
data-state~="disabled".nds-radio-groupDisables all radio inputs in the group via the forms state hook
data-state~="readonly".nds-radio-containerFreezes the tile border to the disabled color while leaving the input interactive

CSS Custom Properties

PropertyDefaultDescription
--radio-tile-bg--background-defaultBackground fill of the radio tile (unchecked state)
--radio-tile-border--controls-borderOutline ring color of the tile (unchecked state)
--radio-primary-checked--controls-primary-checkedTile fill color when the primary radio is checked
--radio-primary-hovered--controls-primary-hoveredTile fill color on hover of a checked primary radio
--radio-primary-pressed--controls-primary-pressedTile fill color on press of a checked primary radio
--radio-neutral-checked--controls-neutral-checkedTile fill color when the neutral radio is checked
--radio-neutral-hovered--controls-neutral-hoveredTile fill color on hover of a checked neutral radio
--radio-neutral-pressed--controls-neutral-pressedTile fill color on press of a checked neutral radio

Validation Attributes

  • Add data-required to the group to require a selection before form submission
  • Add data-error-message on the group to override the default validation message
  • Place a nds-form-footer with data-feedback-target inside the group for dynamic feedback placement
  • Use data-state="disabled" on the group to disable all radio buttons at once
Last Modified Date: 28/06/2026 - 01:27 PM
Was this page useful?
60% of users said Yes from 2843 Feedbacks