Skip to main content

This is a guide on using the GOV.UK Design System Form Builder

  1. Index
  2. Radio buttons

Radio buttons

Radio buttons allow users to select a single option from a list.

Radios are grouped together in a fieldset with a legend that describes them, as shown in the examples on this page.

If you are asking just one question per page as recommended, you can set the contents of the legend as the page heading. This is good practice as it means that users of screen readers will only hear the contents once.

Radio buttons collection with legend and hint text

Data

departments = [
  OpenStruct.new(id: 1, name: 'Sales'),
  OpenStruct.new(id: 2, name: 'Marketing'),
  OpenStruct.new(id: 3, name: 'Finance')
]

Input

= f.govuk_collection_radio_buttons :new_department_id,
  departments,
  :id,
  :name,
  legend: { text: 'Which department do you work for?' },
  hint_text: 'There should be a sign near your desk'

Rendered output

Which department do you work for?

There should be a sign near your desk

HTML output

<div class="govuk-form-group">
  <fieldset class="govuk-fieldset" aria-describedby="person-new-department-id-hint">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--m">
      <h1 class="govuk-fieldset__heading">
        Which department do you work for?
      </h1>
    </legend>
    <span class="govuk-hint" id="person-new-department-id-hint">
      There should be a sign near your desk
    </span>
    <div class="govuk-radios" data-module="govuk-radios">
      <div class="govuk-radios__item">
        <input id="person-new-department-id-1-field" class="govuk-radios__input" type="radio" value="1" name="person[new_department_id]" />
        <label for="person-new-department-id-1-field" class="govuk-label govuk-radios__label">
          Sales
        </label>
      </div>
      <div class="govuk-radios__item">
        <input id="person-new-department-id-2-field" class="govuk-radios__input" type="radio" value="2" name="person[new_department_id]" />
        <label for="person-new-department-id-2-field" class="govuk-label govuk-radios__label">
          Marketing
        </label>
      </div>
      <div class="govuk-radios__item">
        <input id="person-new-department-id-3-field" class="govuk-radios__input" type="radio" value="3" name="person[new_department_id]" />
        <label for="person-new-department-id-3-field" class="govuk-label govuk-radios__label">
          Finance
        </label>
      </div>
    </div>
  </fieldset>
</div>

Radio buttons collection with descriptions

Adding conditional content

Often radio buttons need a description to help the user pick the correct option. In addition to Rails’ collection form helper taking arguments for the identifier and label text for radio buttons, an extra argument can be passed for the description.

In this example, our source data has a description attribute which we want to form the hint text. The attribute name will be called on each option and if a description is present it will be displayed, if it is null or empty no hint will be rendered.

When descriptions are enabled in a radio button collection the labels are made bold by default. This provides additional contrast and makes the labels stand out from the hint.

Data

lunch_options = [
  OpenStruct.new(
    id: 1,
    name: 'Salad',
    description: 'Lettuce, tomato and cucumber'
  ),
  OpenStruct.new(
    id: 2,
    name: 'Jacket potato',
    description: 'With cheese and baked beans'
  )
]

Input

= f.govuk_collection_radio_buttons :lunch_id,
  lunch_options,
  :id,
  :name,
  :description,
  legend: { text: 'What would you like for lunch?' }

Rendered output

What would you like for lunch?

Lettuce, tomato and cucumber
With cheese and baked beans

HTML output

<div class="govuk-form-group">
  <fieldset class="govuk-fieldset">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--m">
      <h1 class="govuk-fieldset__heading">
        What would you like for lunch?
      </h1>
    </legend>
    <div class="govuk-radios" data-module="govuk-radios">
      <div class="govuk-radios__item">
        <input id="person-lunch-id-1-field" aria-describedby="person-lunch-id-1-hint" class="govuk-radios__input" type="radio" value="1" name="person[lunch_id]" />
        <label for="person-lunch-id-1-field" class="govuk-label govuk-label--s govuk-radios__label">
          Salad
        </label>
        <span class="govuk-hint govuk-radios__hint" id="person-lunch-id-1-hint">
          Lettuce, tomato and cucumber
        </span>
      </div>
      <div class="govuk-radios__item">
        <input id="person-lunch-id-2-field" aria-describedby="person-lunch-id-2-hint" class="govuk-radios__input" type="radio" value="2" name="person[lunch_id]" />
        <label for="person-lunch-id-2-field" class="govuk-label govuk-label--s govuk-radios__label">
          Jacket potato
        </label>
        <span class="govuk-hint govuk-radios__hint" id="person-lunch-id-2-hint">
          With cheese and baked beans
        </span>
      </div>
    </div>
  </fieldset>
</div>

Small radio buttons

Use standard-sized radios in nearly all cases. However, smaller versions work well on pages where it’s helpful to make them less visually prominent.

For example, on a page of search results, the primary user need is to see the results. Using smaller radios lets users see and change search filters without distracting them from the main content.

Data

lunch_options = [
  OpenStruct.new(
    id: 1,
    name: 'Salad',
    description: 'Lettuce, tomato and cucumber'
  ),
  OpenStruct.new(
    id: 2,
    name: 'Jacket potato',
    description: 'With cheese and baked beans'
  )
]

Input

= f.govuk_collection_radio_buttons :wednesday_lunch_id,
  lunch_options,
  :id,
  :name,
  :description,
  small: true,
  legend: { text: 'What would you like for lunch on Wednesday?' }

Rendered output

What would you like for lunch on Wednesday?

Lettuce, tomato and cucumber
With cheese and baked beans

HTML output

<div class="govuk-form-group">
  <fieldset class="govuk-fieldset">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--m">
      <h1 class="govuk-fieldset__heading">
        What would you like for lunch on Wednesday?
      </h1>
    </legend>
    <div class="govuk-radios govuk-radios--small" data-module="govuk-radios">
      <div class="govuk-radios__item">
        <input id="person-wednesday-lunch-id-1-field" aria-describedby="person-wednesday-lunch-id-1-hint" class="govuk-radios__input" type="radio" value="1" name="person[wednesday_lunch_id]" />
        <label for="person-wednesday-lunch-id-1-field" class="govuk-label govuk-label--s govuk-radios__label">
          Salad
        </label>
        <span class="govuk-hint govuk-radios__hint" id="person-wednesday-lunch-id-1-hint">
          Lettuce, tomato and cucumber
        </span>
      </div>
      <div class="govuk-radios__item">
        <input id="person-wednesday-lunch-id-2-field" aria-describedby="person-wednesday-lunch-id-2-hint" class="govuk-radios__input" type="radio" value="2" name="person[wednesday_lunch_id]" />
        <label for="person-wednesday-lunch-id-2-field" class="govuk-label govuk-label--s govuk-radios__label">
          Jacket potato
        </label>
        <span class="govuk-hint govuk-radios__hint" id="person-wednesday-lunch-id-2-hint">
          With cheese and baked beans
        </span>
      </div>
    </div>
  </fieldset>
</div>

Inline radio buttons

When there are only two options, you can either stack the radios or display them inline.

Input

= f.govuk_collection_radio_buttons :thursday_lunch_id,
  lunch_options,
  :id,
  :name,
  inline: true,
  legend: { text: 'What would you like for lunch on Thursday?' }

Rendered output

What would you like for lunch on Thursday?

HTML output

<div class="govuk-form-group">
  <fieldset class="govuk-fieldset">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--m">
      <h1 class="govuk-fieldset__heading">
        What would you like for lunch on Thursday?
      </h1>
    </legend>
    <div class="govuk-radios govuk-radios--inline" data-module="govuk-radios">
      <div class="govuk-radios__item">
        <input id="person-thursday-lunch-id-1-field" class="govuk-radios__input" type="radio" value="1" name="person[thursday_lunch_id]" />
        <label for="person-thursday-lunch-id-1-field" class="govuk-label govuk-radios__label">
          Salad
        </label>
      </div>
      <div class="govuk-radios__item">
        <input id="person-thursday-lunch-id-2-field" class="govuk-radios__input" type="radio" value="2" name="person[thursday_lunch_id]" />
        <label for="person-thursday-lunch-id-2-field" class="govuk-label govuk-radios__label">
          Jacket potato
        </label>
      </div>
    </div>
  </fieldset>
</div>

Radio buttons collection with conditional content and a divider

Adding conditional content

If your list of options is hard-coded or you want to add extra customisation, like inserting a text divider, the #govuk_radio_button_fieldset helper offers additional flexibility.

Any content passed into #govuk_radio_button as a block will be revealed when the radio button is selected.

Input

= f.govuk_radio_buttons_fieldset(:old_department_id, legend: { size: 'm', text: 'Which department do you work in?' }) do
  = f.govuk_radio_button :old_department_id, 'it', label: { text: 'Information Technology' }
  = f.govuk_radio_button :old_department_id, 'marketing', label: { text: 'Marketing' }
  = f.govuk_radio_divider
  = f.govuk_radio_button :old_department_id, 'other', label: { text: 'Other' } do
    = f.govuk_text_field :old_department_description,
      label: { text: 'Which department did you work in most recently?' }

Rendered output

Which department do you work in?

or

HTML output

<div class="govuk-form-group">
  <fieldset class="govuk-fieldset">
    <legend class="govuk-fieldset__legend govuk-fieldset__legend--m">
      <h1 class="govuk-fieldset__heading">
        Which department do you work in?
      </h1>
    </legend>
    <div class="govuk-radios" data-module="govuk-radios">
      <div class="govuk-radios__item">
        <input id="person-old-department-id-it-field" class="govuk-radios__input" type="radio" value="it" name="person[old_department_id]" />
        <label for="person-old-department-id-it-field" class="govuk-label govuk-radios__label">
          Information Technology
        </label>
      </div>
      <div class="govuk-radios__item">
        <input id="person-old-department-id-marketing-field" class="govuk-radios__input" type="radio" value="marketing" name="person[old_department_id]" />
        <label for="person-old-department-id-marketing-field" class="govuk-label govuk-radios__label">
          Marketing
        </label>
      </div>
      <div class="govuk-radios__divider">
        or
      </div>
      <div class="govuk-radios__item">
        <input id="person-old-department-id-other-field" data-aria-controls="person-old-department-id-other-conditional" class="govuk-radios__input" type="radio" value="other" name="person[old_department_id]" />
        <label for="person-old-department-id-other-field" class="govuk-label govuk-radios__label">
          Other
        </label>
      </div>
      <div class="govuk-radios__conditional govuk-radios__conditional--hidden" id="person-old-department-id-other-conditional">
        <div class="govuk-form-group">
          <label for="person-old-department-description-field" class="govuk-label">
            Which department did you work in most recently?
          </label>
          <input id="person-old-department-description-field" class="govuk-input" type="text" name="person[old_department_description]" />
        </div>
      </div>
    </div>
  </fieldset>
</div>

Populating values, labels and hints with procs

It’s often convenient to hold label and hint text in locale or configuration files. This approach allows content changes to be made in the repository rather than modifying via data migrations.

To support this behaviour the form builder allows Ruby Procs to be supplied for the :value_method, :text_method and :hint_method parameters. They each take a single argument, item, which is object representing the radio button.

Data

laptops = %i(thinkpad xps macbook_pro zenbook)

Localisation data

laptops:
  names:
    thinkpad: Lenovo ThinkPad X1 Carbon
    macbook_pro: MacBook Pro
    xps: Dell XPS
    zenbook: Asus ZenBook
  descriptions:
    macbook_pro: |-
      The MacBook Pro is a line of Macintosh portable computers
      introduced in January 2006, by Apple Inc.
    thinkpad: |-
      ThinkPad, known for their minimalist, black and boxy design, is a
      line of business-oriented laptops designed, developed, marketed,
      and sold by Lenovo (formerly IBM)
    zenbook: |-
      Zenbook are a family of ultrabooks – low-bulk laptop computers –
      produced by Asus.
    xps: |-
      Dell XPS 'Xtreme Performance System' is a line of high
      performance computers manufactured by Dell.

Input

= f.govuk_collection_radio_buttons :laptop,
  laptops,
  ->(option) { option },
  ->(option) { I18n.t('laptops.names.' + option.to_s) },
  ->(option) { I18n.t('laptops.descriptions.' + option.to_s) },
  legend: { text: "Which laptop would you like to use?" }

Rendered output

Which laptop would you like to use?

ThinkPad, known for their minimalist, black and boxy design, is a line of business-oriented laptops designed, developed, marketed, and sold by Lenovo (formerly IBM)
Dell XPS ‘Xtreme Performance System’ is a line of high performance computers manufactured by Dell.
The MacBook Pro is a line of Macintosh portable computers introduced in January 2006, by Apple Inc.
Zenbook are a family of ultrabooks – low-bulk laptop computers – produced by Asus.