type-in-label
Mobile validation
accessibilityLabel or contentDescription.Assistive technologies already convey an element's type through its built-in semantics, such as its role or traits. Screen readers announce the type by default, for example “button” or “link”. When the accessible name also contains the type, such as “Submit button”, screen readers announce it twice, which adds noise and slows users down. Voice input users may also have to include the extra word in their commands. Remove the type from the accessible name, and let the element's role be announced on its own.
Note: When the type in the name contradicts the element's actual role, for example “Submit, link” on a button, see the related conflicting-type-in-label validation.
Pass Patterns
Android
The button's name comes from its text, with no type in it.
<Button
android:id="@+id/submitButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit" />The clickable element has the button role, and its name contains no type.
Text(
text = "Submit",
modifier = Modifier
.semantics { role = Role.Button }
.clickable { submit() },
)iOS
The button's name comes from its title, with no type in it.
let submitButton = UIButton(type: .system)
submitButton.setTitle("Submit", for: .normal)The button's name comes from its label, with no type in it.
Button {
submit()
} label: {
Text("Submit")
}Cross Platform
The button's name comes from its text, with no type in it.
ElevatedButton(
onPressed: submit,
child: const Text('Submit'),
),The button's name comes from its text, with no type in it.
<Pressable accessibilityRole="button" onPress={submit}>
<Text>Submit</Text>
</Pressable>Fail Patterns
Android
The contentDescription repeats the type, “Button”.
<Button
android:id="@+id/submitButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"
android:contentDescription="Submit, Button" />The contentDescription repeats the type, “Button”.
Text(
text = "Submit",
modifier = Modifier
.semantics {
role = Role.Button
contentDescription = "Submit, Button"
}
.clickable { submit() },
)iOS
The accessibilityLabel repeats the type, “Button”.
let submitButton = UIButton(type: .system)
submitButton.setTitle("Submit", for: .normal)
submitButton.accessibilityLabel = "Submit, Button"The button's label repeats the type, “button”.
Button {
submit()
} label: {
Text("Submit button")
}Cross Platform
The Semantics label repeats the type, “Button”.
Semantics(
label: 'Submit, Button',
button: true,
excludeSemantics: true,
child: ElevatedButton(
onPressed: submit,
child: const Text('Submit'),
),
),The accessibilityLabel repeats the type, “Button”.
<Pressable
accessibilityRole="button"
accessibilityLabel="Submit, Button"
onPress={submit}
>
<Text>Submit</Text>
</Pressable>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 to move to the element.
- Listen to the element's name and its role.
Expected results: The screen reader announces the element's type once, for example “Submit, button”.
Actual results: The screen reader announces the type twice, once from the name and once from the element's role, for example “Submit, button, button”.
Tip: To hear the type more easily, set the screen reader to announce it first. On Android, open TalkBack settings > Advanced settings > Element description order and choose "Type, name, state". On iOS, open Settings > Accessibility > VoiceOver > Verbosity > Controls and choose "Speak Before".
Using developer tools
- iOS: In Xcode, open Xcode > Open Developer Tool > Accessibility Inspector, select the simulator or device, and point at the element. Check its Label.
- Android: In Android Studio, open the Layout Inspector and select the element. Check its
contentDescription, for Views, or its semantics, for Jetpack Compose.
Expected results: The name contains no type, such as “button”, “link”, or “image”.
Actual results: The name contains the element's type.
FAQ
Why is this issue marked as Minor?
The element remains identifiable and operable. The repeated type only adds unnecessary words to the announcement, so the impact is limited, and it is rated minor.
Standards and Regulations
Personas impacted by this issue
Learn More
- Apple Human Interface Guidelines: Guidelines for Creating Labels
- Android: Describe each UI element
- Apple: accessibilityLabel (UIKit)
- Apple: accessibilityLabel(_:) (SwiftUI)