<fieldset class="r-pill"> <legend>Group Title</legend> <div class="r-pill__group"> <!-- optional styling wrapper --> <span class="r-pill__item"> <input type="radio" id="r1" name="radios" checked> <label for="r1">Option 1</label> </span> <span class="r-pill__item"> <input type="radio" id="r2" name="radios"> <label for="r2">Option 2</label> </span> </div> </fieldset>
As with the styled radio buttons pattern, the radio button pills also utilize visually hidden native HTML radio buttons as the cornerstone for providing the necessary semantics and user experience for keyboard users, and the accessibility API.
The radio buttons are wrapped in a
fieldset element. The presence of the
fieldset element groups the radio buttons and programmatically communicates that they are functionally interdependent. The
legend element provides a description of the grouped radio buttons' purpose.
If it makes sense for the grouping of radio buttons to be called out in the document outline, then the
legend can incorporate an appropriately ranked heading element (e.g.
The form control with the
checked attribute applied to it will trigger a CSS selector that visually updates the appearance of the sibling
label associated with it, indicating that it is the selected option. As there is no way to deselect a radio button, without also resetting an entire form or including a radio button option specifically to indicate a "no selection", a radio button pill should always have a radio button set with a default
A selector targeting the last
:after pseudo-element will create an outline around the entire component to indicate it has keyboard focus and can be interacted with.
Affects on Screen Reader Announcements?
Since the native radio buttons remain in the DOM, and are used as the focusable elements that control the state of their custom visualization, there are no alterations to how a screen reader announces keyboard focused styled radio buttons.
Using standard visually hidden CSS to hide the native radio button off screen, or as a single pixel in the document, will mean that certain screen reader users might be unable to locate the radio button. For instance, those searching by touch, or using a mouse while a screen reader announces what is being hovered. To mitigate this, the radio buttons have been positioned on top of their styled
labels, yet still styled to be visually hidden. Note that NVDA does not announce the radio button role when hovered by mouse, regardless of it being styled or not, unless default NVDA settings are changed.
When a radio button is receives keyboard focus, screen readers like JAWS and NVDA may automatically go into forms mode, or require a user to hit Enter or Space to focus into the radio button, depending on the user's settings. Then arrow keys can be used to select the different radio buttons, as expected in forms mode.
VoiceOver on macOS may begin to focus the radio button labels when using arrow keys to change the selected radio button. This issue does not exist in VoiceOver + Chrome and is not necessarily unique to this particular styling of radio buttons.
Radio buttons are meant to indicate a group of single choice options, typically part of a larger form area of a document. It may be acceptable to a pattern like this outside of the context of a form, as long as reverting state is a simple process for the user, and the user is aware of the effect the state change will have on the UI. Be mindful of WCAG 3.2.2, On Input.
Alternatively, a grouping of
button elements that are aware of each other's state, and utilize
aria-pressed="true/false" to indicate their own state, may be more appropriate and understandable to users.