react-strict-dom icon indicating copy to clipboard operation
react-strict-dom copied to clipboard

Accessibility issues with screen reader in apps

Open EmmaDawsonDev opened this issue 9 months ago • 4 comments

Describe the issue

Myself and some colleagues have been asked to evaluate the accessibility of React Strict DOM for possible use in an e-commerce app that falls under the new European Accessibility Act that comes into force in June.

So far we noticed that none of the elements are announced correctly with a screen reader in iOS (VoiceOver) or android (TalkBack). With some experimentation we've managed to get heading tags to be announced as headings by adding role="heading" to the h1 - h6 tags but other elements we have had no luck with such as adding role="list" to ol and ul tags.

Is there something we are missing in order to get this to work or is this a limit of the library at the moment? If it is a limit, do you have it on the roadmap to map the accessibility roles from html correctly to native elements?

Expected behavior

Buttons should announce as buttons Links on webpages should announce as links but maybe should announce as buttons on native considering href isn't supported Headings should announce as headings Lists should announce as lists and how many items they contain Inputs, selects and textareas should announce the programmatically associated label

Steps to reproduce

Open an app on iOS or android and start the corresponding screen reader. Swipe through the content to hear the lack of semantic information.

Test case

No response

Additional comments

No response

EmmaDawsonDev avatar Mar 25 '25 12:03 EmmaDawsonDev

Hi,

React Strict DOM delegates everything to React Native for native platforms. Given the need to translate specific HTML APIs into those provided by React Native, it's helpful to include the example code that you're writing or a link to a test case. It will result in less confusion or back-and-forth.

With some experimentation we've managed to get heading tags to be announced as headings by adding role="heading" to the h1 - h6 tags but other elements we have had no luck with such as adding role="list" to ol and ul tags.

We should add those roles by default to the native element when those HTML tags are used. However, in the meantime...

Adding role to any element will forward that property to React Native. These are the roles supported in React Native - https://reactnative.dev/docs/accessibility#role

If I add role="list", I see it turn up in the snapshots and I see it on the React Native element in the DevTools inspector.

Image

If you're still not hearing it announced, it might be a problem with React Native's implementation of role - the prop might show up on the native element but not do anything. For example, if rendering a View with role="list" has the same issue, but using accessibilityRole="list" doesn't. If you find that React Native's role is not working but accessibilityRole is, we can try switching the implementation in React Strict DOM to accessibilityRole.

Lists should announce as lists and how many items they contain.

This is dependent upon the accessibility implementation in React Native. It depends on whether native platforms announce how many items are in a list, and if React Native implements the relevant platform APIs to enable this.

Inputs, selects and textareas should announce the programmatically associated label.

What markup are you using to create this association? If you look at the HTML compatibility table you'll see that for is not supported on native but aria-labelledby is (maybe just on Android though)

necolas avatar Mar 25 '25 17:03 necolas

We should add those roles by default to the native element when those HTML tags are used

https://github.com/facebook/react-strict-dom/pull/286

necolas avatar Mar 25 '25 18:03 necolas

Thanks for the quick response. I will check how list responds in react native and come back with the results.

For labels and inputs, using the "for" and "id" as is the expected way in html does not work. On iOS I could get it to work with aria-label on the input but not aria-labelledby. I will ask my colleague to test on android. Will the "for" attribute never be supported or is it something that is on the roadmap for the future/waiting for someone to make a PR? ie How should the red crosses on the compatibility table be interpreted?

EmmaDawsonDev avatar Mar 26 '25 08:03 EmmaDawsonDev

The vast majority of the unsupported features require new capabilities to be built into React Native. We've largely exhausted all the polyfills we can do here (and the ability to polyfill accessibility features is more limited).

Unfortunately, at the moment, I don't think there is much investment into further bridging the gap from the React Native side beyond a few key functional areas like events. More demand from the community in the form of opening issues about React Native accessibility asks / issues can help.

Accessibility in React Native isn't the best, and faithfully reproducing web's accessibility patterns is limited by what is provided by native platforms, as that is the approach React Native currently takes (as opposed to writing a custom implementation of ARIA etc). It does look like iOS might have APIs for associating text elements with inputs (accessibilityinputlabels), but that isn't exposed in React Native at the moment.

If you were to use RSD, you could create your own components that manage the divergence in capabilities between platforms while they exist. For example, on web you'd keep the for/id approach, on Android you'd use aria-labelledby, and on iOS you'd fallback to aria-label. I'm not sure how a browser would handle all 3 approaches used at once - so if that's a problem you can use the file forks (*.js / *.android.js / *.ios.js) to target individual platforms with different implementations.

necolas avatar Mar 26 '25 17:03 necolas

Closing this as I'm assuming my posts answered the questions. We've also merged some improvements to automatically add accessibility roles on native, by inferring from the role from the HTML tag name

necolas avatar Jun 10 '25 19:06 necolas