Skip to content

Radio

Native radio buttons styled with .re-radio. The native name groups radios and arrow keys traverse the group.

Plan
Live example
<fieldset class="re-field-group">
  <legend class="re-field-group__legend">Plan</legend>
  <div class="re-field-group__items">
    <label class="re-field re-field--inline">
      <input class="re-radio" type="radio" name="plan" id="rd-free" value="free" checked />
      <span class="re-field__label">Free</span>
    </label>
    <label class="re-field re-field--inline">
      <input class="re-radio" type="radio" name="plan" id="rd-pro" value="pro" />
      <span class="re-field__label">Pro</span>
    </label>
    <label class="re-field re-field--inline">
      <input class="re-radio" type="radio" name="plan" id="rd-team" value="team" />
      <span class="re-field__label">Team</span>
    </label>
  </div>
</fieldset>
Size
Live example
<fieldset class="re-field-group" data-orientation="horizontal">
  <legend class="re-field-group__legend">Size</legend>
  <div class="re-field-group__items">
    <label class="re-field re-field--inline">
      <input class="re-radio" type="radio" name="size" id="rd-s" value="s" />
      <span class="re-field__label">S</span>
    </label>
    <label class="re-field re-field--inline">
      <input class="re-radio" type="radio" name="size" id="rd-m" value="m" />
      <span class="re-field__label">M</span>
    </label>
    <label class="re-field re-field--inline">
      <input class="re-radio" type="radio" name="size" id="rd-l" value="l" />
      <span class="re-field__label">L</span>
    </label>
  </div>
</fieldset>
Live example
<div class="stack">
  <label class="re-field re-field--inline">
    <input class="re-radio" type="radio" name="state" id="rd-disabled" disabled />
    <span class="re-field__label">Disabled</span>
  </label>
  <label class="re-field re-field--inline">
    <input class="re-radio" type="radio" name="state" id="rd-invalid" aria-invalid="true" />
    <span class="re-field__label">Invalid</span>
  </label>
</div>
  • Keyboard — fully native, no JavaScript keyboard layer. Radios sharing a name form a single tab stop: Tab moves into the checked radio (or the first one if none is checked), and Arrow keys move the selection between radios in the group, as the browser provides. Space selects the focused radio.
  • Focus — a visible ring shows only on :focus-visible (keyboard focus), drawn as a box-shadow (--re-shadow-focus) plus a focus-ring border color so it stays crisp at the radio’s pill radius.
  • Semantics — each control stays a real <input type="radio">, so the accessible role, selected state, and form serialization are all native. Wrapping the input in <label class="re-field re-field--inline"> with the .re-field__label text gives an implicit label that’s announced as the radio’s name and makes the whole label a click/tap target. Wrap the set in <fieldset class="re-field-group"> with a <legend class="re-field-group__legend"> so the group’s name (e.g. “Plan”) is announced alongside each option.
  • Notes — for validation, set aria-invalid="true" on the input (it tints the border via --re-color-danger-border). The checked dot is drawn with ::before rather than an SVG asset so the input stays native, and a @media (forced-colors: active) block re-establishes the checked fill with system Highlight / HighlightText so a selected radio stays distinct from unselected ones in Windows High Contrast. data-orientation="horizontal" on the group is presentational only and changes nothing about the announced structure. See Checkbox, Field Group, and the accessibility guide.