Skip to content

Accessibility Behavior

Maciej Jastrzebski edited this page Oct 8, 2022 · 11 revisions

Methods of testing:

  • iOS: using Accessibility Inspector (in iOS mode!) on iOS simulator
  • Android: using TalkBack on Android emulator

<Text> component

<Text> behavior in iOS

ComponentScreen readerLabelValueTraitsIdentifierHintUser Input Label
<Text>Hello!</Text>Hello!Hello !(none)Static Text(none)(none)Hello !
accessible={true} accessibilityRole="text"Hello!Hello !(none)Static Text(none)(none)Hello !
accessible={true}Hello!Hello !(none)Static Text(none)(none)Hello !
accessible={false}(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)
accessibilityRole="text"Hello!Hello !(none)Static Text(none)(none)Hello !
accessibilityRole="none"Hello!Hello !(none)(none)(none)(none)Hello !

Findings:

  • iOS behaves the same for when accessible={true} or when prop is not specified
  • iOS behaves the same for when accessibilityRole="text" or when prop is not specified
  • iOS ignores element when accessible={false}
  • changing accessibilityRole to "none" removes Static Text trait, but view is still readable by screen reader

<Text> behavior in Android

ComponentScreen reader
<Text >Hello!</Text>Hello!
accessible={true} accessibilityRole="text"Hello!
accessible={true}Hello!
accessible={false}Hello!
accessibilityRole="text"Hello!
accessibilityRole="none"Hello!
importantForAccessibility="no"(ignored)
importantForAccessibility="no-hide-descendants"(ignored)

Findings:

  • Android accessible props does not affect TalkBack screen reader behaviour
  • Android accessibilityRole props does not affect TalkBack screen reader behaviour
  • Android ignores element if importantForAccessibility value "no" or "no-hide-descendants"

<Text> handling recommendations

  • assume default accessible value of true
  • assume default accessibilityRole of text
  • assume none role when accessibilityRole="none"
  • assume excluded from accessibility when accessible={false} (based on iOS semantics)
  • assume excluded from accessibility role when importantForAccessibility="no" or importantForAccessibility="no-hide-descendants" (based on Android semantics)

<TextInput> component

<TextInput> behavior in iOS

ComponentScreen readerLabelValueTraitsIdentifierHintUser Input Label
<TextInput defaultValue="Hello" />Hello(none)Hello(empty)(none)(none)Hello
accessible={true}Hello(none)Hello(empty)(none)(none)Hello
accessible={false}Hello(none)Hello(empty)(none)(none)Hello
accessibilityRole="searchHello - search field(none)HelloSearch Field(none)(none)Search Field
accessibilityRole="none"Hello(none)Hello(empty)(none)(none)Hello
editable={false}Hello - not enabled(none)HelloNot enabled(none)(none)Hello

Findings:

  • iOS ignores accessible={false} attribute, it behaves the same as default and true value
  • iOS ignores accessibilityRole="none" the elements behaves the same as without role attribute
  • iOS reacts to accessibilityRole="search" by reading the "serach field" trait name
  • iOS reacts to editable={false} by reading the "not enabled" trait name

<TextInput> behavior in Android

ComponentScreen reader
<TextInput defaultValue="Hello" />Hello - edit box - double tap to edit text - double tap and hold to long press
accessible={true}Hello - edit box - double tap to edit text - double tap and hold to long press
accessible={false}Hello - edit box - double tap to edit text - double tap and hold to long press
accessibilityRole="searchHello - edit box - double tap to edit text - double tap and hold to long press
accessibilityRole="noneHello - edit box - double tap to activate - double tap and hold to long press
editable={false}Hello - edit box - disabled
importantForAccessibility="no"(ignored)
importantForAccessibility="no-hide-descendants"(ignored)

Findings:

  • Android ignores accessible={false} attribute, it behaves the same as default and true value
  • Android ignores accessibilityRole="search" the elements behaves the same as without role attribute
  • Android slight alters the read text when accessibilityRole="none", it says "double tap to activate" instead of "to edit text"

<TextInput> handling recommendations

  • assume "search" role when accessibilityRole="search"
  • assume excluded from accessibility role when importantForAccessibility="no" or importantForAccessibility="no-hide-descendants" (based on Android semantics)
  • assume accessibilityState disabled when editable={false}
  • consider assuming excluded from accessibility when accessible={false} (based on other elements behavior) TextInput behavior might be a bug
  • consider assuming implicit ARIA role of textbox when no explicit role is provided (based on the fact that Android reads "edit box" hint

<View> component

<View> behavior in iOS

ComponentScreen readerLabelValueTraitsIdentifierHintUser Input Label
<View />(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)
accessible={true}Description for element unavailable(none)(none)(empty)(none)(none)(Empty Array)
accessible={false}(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)
accessibilityRole="button"(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)
accessibilityRole="none"(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)
onPress={() => {}}(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)(ignored)
accessible={true} accessibilityRole="button"Button(ignored)(ignored)Button(ignored)(ignored)(ignored)

Findings:

  • iOS ignores element when accessible={false} or when prop is not specified
  • iOS notices element when accessible={true}
  • iOS notices accessibilityRole only when accessible={true}
  • setting accessibilityRole or onPress alone does not affect iOS

<View> behavior in Android

ComponentScreen reader
<View />(ignored)
accessible={true}(nothing, but focusable)
accessible={false}(ignored)
accessibilityRole="button"(ignored)
accessibilityRole="none"(ignored)
onPress={() => {}}(ignored)
accessible={true} accessibilityRole="button"Button - double tap to activate
importantForAccessibility="yes"(ignored)

Findings:

  • Android ignores element when accessible={false} or when prop is not specified
  • Android notices element when accessible={true} (becomes focusable)
  • Android notices accessibilityRole only when accessible={true} (reads the role)
  • setting accessibilityRole or onPress alone does not affect Android
  • Android ignores element if importantForAccessibility value "yes"

<View> handling recommendations

  • assume default accessible value of false
  • assume excluded from accessibility when accessible={false} or default
  • assume has default role "none" when accessible={true}