Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[a11y] Nested accessibility items are not respected on iOS #24515

Open
sahrens opened this issue Apr 18, 2019 · 9 comments
Open

[a11y] Nested accessibility items are not respected on iOS #24515

sahrens opened this issue Apr 18, 2019 · 9 comments
Labels
Accessibility Team - Evaluated Accessibility Bug Never gets stale Prevent those issues and PRs from getting stale Platform: iOS iOS applications. Ran Commands One of our bots successfully processed a command.

Comments

@sahrens
Copy link
Contributor

sahrens commented Apr 18, 2019

React Native apps often have many UI components that are touchable but also contain nested elements that are also touchable. For example, an entire list row may be touchable as a primary navigation option, but it might also have an auxiliary button nested inside of it for taking a specific action, like delete or save.

Currently, if the touchable wrapper for the auxiliary button as well as the row container are properly tagged with accessibility props and accessibility labels it works fine on Android but on iOS, the nested 'save/delete' button is not selectable by VoiceOver. On Android, both will be accessible when accessibility features are enabled.

The current workaround in user-land is to make some janky hierachry where the aux button is a sibling of its visual container, which often breaks encapsulation and is generally a pain.

There are a couple ways we might be able to work around this at the framework level:

  1. use UIAccessibilityContainer protocol
  2. set the accessibilityElements property on the parent

Those approaches are detailed a bit more here:
https://stackoverflow.com/questions/38849389/voiceover-parent-and-child-views-as-accessibility-elements

Looks like flutter had this same issue and fixed it here with UIAccessibilityContainer: flutter/engine#4110

Tracked internally with T34121499

@react-native-bot
Copy link
Collaborator

Thanks for submitting your issue. Can you take another look at your description and make sure the issue template has been filled in its entirety?

👉 Click here if you want to take another look at the Bug Report issue template.

@react-native-bot react-native-bot added Ran Commands One of our bots successfully processed a command. Resolution: Needs More Information labels Apr 18, 2019
@jessebeach
Copy link

@sahrens this is also true on Web for roles that flatten their children into text, known as childPresentational.

https://www.w3.org/TR/wai-aria-1.1/#childrenArePresentational

Only Android allows nesting of interactive accessibility nodes within interactive accessibility nodes. We should disallow this practice altogether at the React Native level in order to satisfy the constraints of all target platforms. React Native should throw a run-time error when this nesting is detected. That would solve a category of issues that we're constantly chasing down on iOS and Web.

@sahrens
Copy link
Contributor Author

sahrens commented Apr 19, 2019

@jessebeach: generally we try not to limit experiences based on lowest common denominator (especially if there are workarounds like flutter uses), but I agree we need to address this in a way that developers aren’t easily shooting themselves in the foot with a11y. Accessory buttons in list items are a particularly common pattern - what’s the recommended way to make them accessible?

@necolas: how have you dealt with this on react-native-web?

@necolas
Copy link
Contributor

necolas commented Apr 19, 2019

I haven't yet. But I have been planning to add runtime errors when nesting elements with accessibilityRole of link or button to avoid people stumbling into these issues.

You can still have nested Touchables without problem as long as the ancestral ones aren't given link or button roles. That allows mouse, touch, and keyboard interactions to function as expected but requires a little care if the functionality of the outer Touchable isn't redundant. Something like touching a twitter post navigates to the permalink, and the timestamp is marked up as a link for screen readers to be able to navigate there too. If you don't have redundancy you need to fall back to Touchables as siblings and use tricks like absolute positioning (emulating the background layer) to place them visually over each other.

@jessebeach
Copy link

jessebeach commented Apr 19, 2019

If you don't have redundancy you need to fall back to Touchables as siblings and use tricks like absolute positioning (emulating the background layer) to place them visually over each other.

Accessory buttons in list items are a particularly common pattern - what’s the recommended way to make them accessible?

@necolas provided the answer here. The trick is to think of the link item not as the container, but as a sibling interactive element. The accessory buttons are siblings to it. The list item and the accessories are contained in a common parent node. The visual presentation gives the appearance of the list item interactive as the parent container, but that's just presentational fluff.

That's one solution the developer can take. She might however decide to use aria-activedescendant on Web or Rotor secondary actions on iOS. This is an implementation detail and depends on the design. The takeaway is, there are ways to build around the no-nesting limitation in developer land.

@sahrens
Copy link
Contributor Author

sahrens commented Apr 19, 2019 via email

@necolas
Copy link
Contributor

necolas commented Apr 19, 2019

Turns out React already prints warnings to the console if you nest links or buttons.

is it feasible on web too

Not sure but it might be quite complicated as you'd need to preserve all the other expectations around nesting elements even thought they're not actually nested in the DOM.

@stale
Copy link

stale bot commented Aug 4, 2019

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Aug 4, 2019
@stale
Copy link

stale bot commented Aug 11, 2019

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.

@stale stale bot closed this as completed Aug 11, 2019
@facebook facebook locked as resolved and limited conversation to collaborators Aug 12, 2019
@necolas necolas reopened this Oct 11, 2021
@cortinico cortinico added Never gets stale Prevent those issues and PRs from getting stale and removed Stale There has been a lack of activity on this issue and it may be closed soon. labels Oct 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Accessibility Team - Evaluated Accessibility Bug Never gets stale Prevent those issues and PRs from getting stale Platform: iOS iOS applications. Ran Commands One of our bots successfully processed a command.
Projects
None yet
Development

No branches or pull requests

7 participants