Accessibility

Simplified WCAG guidance

WCAG 2.2 – Levels A and AA only, with dev notes.

Radio button group example

This version fully meets the accessibility requirement (WCAG 2.2) but using the minimum amount of ARIA. Improves clarity and maintainability.

Example

Three choices shown, but could range from 2 - 5. Above 5 choices start to consider select / combobox elements instead.

Do you require assistance?

The code

HTML
<radio-button-group>
	<div id="radios-legend">Do you require assistance?</div>
	<div role="radiogroup" aria-labelledby="radios-legend">
		<label>
			<input value="yes" id="assistance_yes" type="radio" name="radios">
			<span>Yes</span>
		</label>
		<label>
			<input value="no" id="assistance_no" type="radio" name="radios">
			<span>No</span>
		</label>
		<label>
			<input value="maybe" id="assistance_maybe" type="radio" name="radios">
			<span>Maybe</span>
		</label>
	</div>
</radio-button-group>

The value attribute is optional.

CSS (opinionated and not a requirement)
CSS
radio-button-group {
	/* Add variables for color as required by the design system
		but ensure WCAG minimum color contrast levels are met
		3:1 for borders and 4.5:1 for text */
	--_border-color-unchecked: XXX;
	--_border-color-checked: XXX;
	--_color-unchecked: XXX;
	--_color-checked: XXX;
	--_background-color-unchecked: XXX;
	--_background-color-checked: XXX;
	--_focus-outline: XXX;

	display: block;
}
radio-button-group [role="radiogroup"] {
	display: flex;
	flex-wrap: wrap;
	gap: 1em;
}
radio-button-group [role="radiogroup"] * {
	margin: 0;
}
radio-button-group [role="radiogroup"] span {
	/* A 2px border is highly recommended */
	border: 2px solid var(--_border-color-unchecked);
	background-color: var(--_background-color-unchecked);
	color: var(--_color-unchecked);
	padding: .5em 1em;
	display: inline-block;
	text-align: center;
	cursor: pointer;
}
radio-button-group [role="radiogroup"] input {
	/* Visually hidden, but not from screen-readers */
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	height: 1px;
	overflow: hidden;
	position: absolute;
	white-space: nowrap;
	width: 1px;
	padding: 0;
}
radio-button-group [role="radiogroup"] input:checked + span {
	border-color: var(--_border-color-checked);
	background-color: var(--_background-color-checked);
	color: var(--_color-checked);
}
radio-button-group [role="radiogroup"] input:focus-visible + span {
	outline: 2px solid var(--_focus-outline);
	outline-offset: 2px;
}