unique-option-names
Mobile validation
Each option in a collection, such as a radio group, a list of choices, or a set of tabs, needs an accessible name. The names must also be unique within the same collection. When two options share a name, screen reader users cannot tell them apart, and voice input users cannot activate the one they want by speaking its name.
Note: This validation covers options within the same collection. For other controls on the screen that share a name, see the related duplicate-name validation.
Pass Patterns
Android
Each radio button in the group has a unique name.
<RadioGroup
android:layout_width="..."
android:layout_height="..."
android:orientation="vertical">
<RadioButton
android:layout_width="..."
android:layout_height="..."
android:text="Small" />
<RadioButton
android:layout_width="..."
android:layout_height="..."
android:text="Large" />
<RadioButton
android:layout_width="..."
android:layout_height="..."
android:text="Extra large" />
</RadioGroup>Each option in the radio group has a unique name.
val sizes = listOf("Small", "Large", "Extra large")
Column(Modifier.selectableGroup()) {
sizes.forEach { size ->
Row(
modifier = Modifier.selectable(
selected = selectedSize == size,
onClick = { selectedSize = size },
role = Role.RadioButton,
),
) {
RadioButton(selected = selectedSize == size, onClick = null)
Text(size)
}
}
}Cross Platform
Each option in the radio group has a unique name.
const sizes = ['Small', 'Large', 'Extra large'];
Column(
children: [
for (final size in sizes)
RadioListTile<String>(
value: size,
groupValue: selectedSize,
onChanged: selectSize,
title: Text(size),
),
],
),Each option in the radio group has a unique name.
const sizes = ['Small', 'Large', 'Extra large'];
<View accessibilityRole="radiogroup">
{sizes.map((size) => (
<Pressable
key={size}
accessibilityRole="radio"
accessibilityState={{ checked: selectedSize === size }}
accessibilityLabel={size}
onPress={() => setSelectedSize(size)}
>
<Text>{size}</Text>
</Pressable>
))}
</View>Fail Patterns
Android
Two radio buttons in the same group are both named “Large”.
<RadioGroup
android:layout_width="..."
android:layout_height="..."
android:orientation="vertical">
<RadioButton
android:layout_width="..."
android:layout_height="..."
android:text="Small" />
<RadioButton
android:layout_width="..."
android:layout_height="..."
android:text="Large" />
<RadioButton
android:layout_width="..."
android:layout_height="..."
android:text="Large" />
</RadioGroup>Two options in the same radio group are both named “Large”.
val sizes = listOf("Small", "Large", "Large")
Column(Modifier.selectableGroup()) {
sizes.forEachIndexed { index, size ->
Row(
modifier = Modifier.selectable(
selected = selectedIndex == index,
onClick = { selectedIndex = index },
role = Role.RadioButton,
),
) {
RadioButton(selected = selectedIndex == index, onClick = null)
Text(size)
}
}
}Cross Platform
Two options in the same radio group are both named “Large”.
const sizes = ['Small', 'Large', 'Large'];
Column(
children: [
for (var i = 0; i < sizes.length; i++)
RadioListTile<int>(
value: i,
groupValue: selectedIndex,
onChanged: selectIndex,
title: Text(sizes[i]),
),
],
),Two options in the same radio group are both named “Large”.
const sizes = ['Small', 'Large', 'Large'];
<View accessibilityRole="radiogroup">
{sizes.map((size, index) => (
<Pressable
key={index}
accessibilityRole="radio"
accessibilityState={{ checked: selectedIndex === index }}
accessibilityLabel={size}
onPress={() => setSelectedIndex(index)}
>
<Text>{size}</Text>
</Pressable>
))}
</View>Try It Yourself
Using a screen reader
New to screen reader testing, or need a refresher?
Review this article first: Practical guides for using screen readers
- Turn on VoiceOver on iOS, or TalkBack on Android.
- Swipe right or left through the options in a collection, such as a radio group or a set of tabs.
- Listen to the name of each option.
Expected results: Each option in the collection has a different name.
Actual results: Two or more options in the same collection are announced with the same name.
Using voice input
New to voice input testing, or need a refresher?
Review this article first: Practical guides for using voice input
- Turn on Voice Control on iOS, or Voice Access on Android.
- Say “Show names” on iOS, or “Show labels” on Android.
- Check the names shown for the options in each collection.
Expected results: Each option shows a unique name that you can say to select it.
Actual results: Several options show the same name, so it cannot be used to select a specific one.
FAQ
Why is this issue marked as Minor?
Users can usually still select the options, but they may need extra effort to tell them apart, or may pick the wrong one. It affects clarity and efficiency rather than blocking a task, so it is rated minor.
How does this issue relate to 4.1.2 Name, Role, Value
WCAG success criterion 4.1.2 requires each user interface component to expose a programmatic name, role, and current state or value so assistive technology can understand and operate it.
When two options in the same collection share an accessible name, their name is not programmatically distinguishable within that set. Assistive technology will announce identical items, and voice input users cannot activate the intended option by speaking its name. Giving each option a unique accessible name within its collection supports conformance with 4.1.2.
Standards and Regulations
| Standard | Success Criterion | Reference |
|---|---|---|
| WCAG 2.2 | 4.1.2 Name, Role, Value (A) | For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies. |
| EN 301 549 | 11.4.1.2 Name, Role, Value | Same as the WCAG text. |
| Section 508 | 1194.21(d) | Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text. |