Skip to content

Hints and errors are not semantically associated with fieldsets #214

Closed

Description

@edwardhorsford

I'm expecting that this library produce output markup that mirrors the design system reference markup.

It looks like hints and error messages are not associated correctly with fieldsets - and thus all items that use fieldset like radios and checkboxes. This is likely an accessibility issue - both that it's not following the reference implementation that's been tested hundreds of times, but also that errors aren't associated at all - and a screen reader user might not get it.

For a set of radios like this:
Screenshot 2024-05-01 at 12 49 15

The reference design system markup is:

<div class="nhsuk-form-group nhsuk-form-group--error">

  <fieldset class="nhsuk-fieldset" aria-describedby="example-error-hint example-error-error">
  <legend class="nhsuk-fieldset__legend">
    Have you changed your name?
  </legend>

  <div class="nhsuk-hint" id="example-error-hint">
    This includes changing your last name or spelling your name differently.
  </div>

  <span class="nhsuk-error-message" id="example-error-error">
    <span class="nhsuk-u-visually-hidden">Error:</span> Select yes if you have changed your name
  </span>

  <div class="nhsuk-radios">
    
    <div class="nhsuk-radios__item">
      <input class="nhsuk-radios__input" id="example-error-1" name="example-error" type="radio" value="yes">
      <label class="nhsuk-label nhsuk-radios__label" for="example-error-1">
        Yes
      </label>
    </div>
    
    
    <div class="nhsuk-radios__item">
      <input class="nhsuk-radios__input" id="example-error-2" name="example-error" type="radio" value="no">
      <label class="nhsuk-label nhsuk-radios__label" for="example-error-2">
        No
      </label>
    </div>
    
  </div>
  </fieldset>

</div>

The markup in story book is:

<div class="nhsuk-form-group nhsuk-form-group--error">
  <fieldset class="nhsuk-fieldset">
    <legend class="nhsuk-fieldset__legend">Have you changed your name?</legend>
    <div class="nhsuk-form-group nhsuk-form-group--error">
      <div class="nhsuk-hint" id="radios_7l6kx--hint">This includes changing your last name or spelling your name differently.</div>
      <span class="nhsuk-error-message" id="radios_7l6kx--error-message" role="alert">
        <span class="nhsuk-u-visually-hidden">Error: </span>Please select an option
      </span>
      <div class="nhsuk-radios" id="radios_7l6kx" aria-describedby="radios_7l6kx--hint">
        <div class="nhsuk-radios__item">
          <input class="nhsuk-radios__input" id="example-1" name="example" aria-labelledby="example-1--label" type="radio" value="yes">
          <label class="nhsuk-label nhsuk-radios__label" id="example-1--label" for="example-1">Yes</label>
        </div>
        <div class="nhsuk-radios__item">
          <input class="nhsuk-radios__input" id="example-2" name="example" aria-labelledby="example-2--label" type="radio" value="no" checked="">
          <label class="nhsuk-label nhsuk-radios__label" id="example-2--label" for="example-2">No</label>
        </div>
      </div>
    </div>
  </fieldset>
</div>

Issues:

  • The hint is not associated with the fieldset (though it is incorrectly associated with a div wrapping the two inputs)
  • The error message is not associated with anything

Activity

  1. edwardhorsford commented on May 3, 2024

    @edwardhorsford
    ContributorAuthor

    Thinking about this some more, I suspect it's because the radios and checkboxes components don't contain the fieldset or legend components - the examples in the storybook have you use those components separately and then nest the checkboses or radios.

    This is a risky approach as it would require end users to manually add the appropriate aria descriptions to fieldsets - developers shouldn't need to worry about this - the component should aim to take care of all markup, given appropriate inputs.

    The way the NHS and GOV.UK design system components handle this is to make fieldset an optional argument to the radio and checkboxes components - if provided, the component wraps itself in the fieldset component and applies the appropriate aria descriptions.

    NHS design system native component:

    {{ radios({
      "idPrefix": "example-error",
      "name": "example-error",
      "errorMessage": {
        "text": "Select yes if you have changed your name"
      },
      "fieldset": {
        "legend": {
          "text": "Have you changed your name?",
          "classes": "nhsuk-fieldset__legend--l",
          "isPageHeading": true
        }
      },
      "hint": {
        "text": "This includes changing your last name or spelling your name differently."
      },
      "items": [
        {
          "value": "yes",
          "text": "Yes"
        },
        {
          "value": "no",
          "text": "No"
        }
      ]
    }) }}

    Here you can see that fieldset is an optional property of radios and checkboxes, and legend is a property of fieldset. I think this this library's radio and checkbox components could be extended to accept these optional properties.

  2. colinrotherham commented on Sep 11, 2025

    @colinrotherham
    Collaborator

    This issue is related to #247 and is fixed in #267

    For example, here are some excerpts from the Upgrading to 6.0 guide


    Date input

    To align with NHS.UK frontend, the date input component automatically renders its own fieldset, legend and associated ARIA attributes. The custom autoSelectNext prop is no longer supported:

      <DateInput
    -   label="What is your date of birth?"
    +   legend="What is your date of birth?"
        hint="For example, 15 3 1984"
    -   autoSelectNext={true}
        value={value}
      />

    Radios

    To align with NHS.UK frontend, the radios component automatically renders its own fieldset, legend and associated ARIA attributes. You must also rename the Radios.Radio component to Radios.Item as shown:

    - <Fieldset>
    -   <Fieldset.Legend>Have you changed your name?</Fieldset.Legend>
    -   <Radios>
    +   <Radios legend="Have you changed your name?">
    -     <Radios.Radio value="yes">Yes</Radios.Radio>
    -     <Radios.Radio value="no">No</Radios.Radio>
    +     <Radios.Item value="yes">Yes</Radios.Item>
    +     <Radios.Item value="no">No</Radios.Item>
        </Radios>
    - </Fieldset>

    Checkboxes

    To align with NHS.UK frontend, the checkboxes component automatically renders its own fieldset, legend and associated ARIA attributes. You must also rename the Checkboxes.Box component to Checkboxes.Item as shown:

    - <Fieldset>
    -   <Fieldset.Legend>What is your nationality?</Fieldset.Legend>
    -   <Checkboxes>
    +   <Checkboxes legend="What is your nationality?">
    -     <Checkboxes.Box value="british">British</Checkboxes.Box>
    -     <Checkboxes.Box value="irish">Irish</Checkboxes.Box>
    -     <Checkboxes.Box value="other">Citizen of another country</Checkboxes.Box>
    +     <Checkboxes.Item value="british">British</Checkboxes.Item>
    +     <Checkboxes.Item value="irish">Irish</Checkboxes.Item>
    +     <Checkboxes.Item value="other">Citizen of another country</Checkboxes.Item>
        </Checkboxes>
    - </Fieldset>
  3. added this to the v6.0.0 milestone on Oct 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions