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

NVDA not reading focused parent #6606

Closed
haltersweb opened this issue Nov 30, 2016 · 16 comments · Fixed by #8869 or #14611
Closed

NVDA not reading focused parent #6606

haltersweb opened this issue Nov 30, 2016 · 16 comments · Fixed by #8869 or #14611
Labels
p4 https://github.com/nvaccess/nvda/blob/master/projectDocs/issues/triage.md#priority
Milestone

Comments

@haltersweb
Copy link

I have an actionable element nested inside of a div with tabindex="-1". When the actionable element is clicked, focus is placed on this parent div. Yet, the div's content is not read by the NVDA screen reader:

  • NVDA Result (in both IE and FF): when I click the actionable element, focus goes to the div but the div's contents are not read.
  • JAWS Result (in both IE and FF): when I click the actionable element, focus goes to the div and the div's contents are read.

But, if the actionable element is outside of the target div, when the div receives focus the contents are read properly.

Here is a code-pen to test with:

@jcsteh
Copy link
Contributor

jcsteh commented Nov 30, 2016

P3 because I can certainly see why this is problematic, but it's extremely difficult to fix. It's possible that a fix for #2039 might fix this.

At present, NVDA ignores focus on an ancestor in this case because the browse mode cursor is already "within" the focused element. The reason for this is that NVDA itself moves the focus when you move the browse mode cursor, but we don't want this focus change to cause spurious reading and to snap the browse mode cursor to the start of the element (which is normally the expected behaviour for focus). There's no reliable way of determining whether a focus change was caused by NVDA itself or by the web page, so we assume focus on an element which already contains the browse mode cursor was caused by NVDA.

@jcsteh jcsteh added the p4 https://github.com/nvaccess/nvda/blob/master/projectDocs/issues/triage.md#priority label Nov 30, 2016
@haltersweb
Copy link
Author

Where I see this being a big issue is with Single-page Applications (SPA).

Typically new content and the controls to advance throuch the SPA are populated into a common container div. So when you try to advance within the SPA through the controls within the container, focus is driven back to the parent container in order for the screen-reader to read all new content and controls.

@haltersweb
Copy link
Author

Here is a "real-world" application. It is an example of a Single Page Application, describing accessibility with SPA: http://haltersweb.github.io/Accessibility/spa.html

@1Copenut
Copy link

1Copenut commented Jan 18, 2018

I'm seeing this behavior, sometimes. Working on a React app that sets focus on the <main> with a ref triggered on componentDidMount(). NVDA reads out the focused section when I manually reload the page, but only starts reading about half the time when loaded via React Router. There doesn't seem to be any pattern; it seems focus is being too early, and NVDA doesn't realize content has changed and it should start reading.

@bobthecavemonkey
Copy link

Could we get an update on this issue? I am working on multiple SPAs and this is causing some major issues. NVDA will not alert the user when new content is displayed. We are displaying new content by hiding our current Div and showing a new Div inside of our SPA container. We are explicitly setting focus on elements in our new content Div in the hopes that NVDA will read this off to the user and alert them a new page is loaded. NVDA doesn't read anything to the user, no matter what I focus on. The only thing that seems to get NVDA to respond is if there are form elements on the new content Div we load.

Below is a jsfiddle that shows the exact problem. When you are using only a keyboard, the new page heading that I focus to isn't read off by NVDA.
https://jsfiddle.net/1wp6mc4w/13/

Again, this is a major issue causing real problems for SPA and this defect has been opened since 2016 with no appropriate response. #2039 is not the same issue that we are dealing with. Please respond to this defect with something of substance.

@BenjaminGolba
Copy link

We have the exact same issues as described in this thread. We have a single page application and in our specific case we have a login screen that switches to a loading screen upon submitting. In this loading screen we put focus on a message that is showing on the loading screen, but nothing is read out by NVDA. Huge problem as this affects our application in many different places.

The problem is very well described by @bobthecavemonkey and is can be reproduced in his jsfiddle.

Any suggestions on how to walk around this issue or perhaps solve it without re-doing a lot of stuff?

@michaelDCurran
Copy link
Member

Reopened as #8869 had to be reverted for now.

@MelSumner
Copy link

MelSumner commented Dec 10, 2018

I'd love to team up with someone on the NVDA side, as I've been working on this from the SPA perspective- specifically, trying to see if we can solve this in Ember.js.

I see that Ember uses the history API in JavaScript frameworks- an API that came after the implementation of screen readers. Specifically, history.pushState, while useful for quick navigation (among other things) seems to not trigger the type of event that NVDA seems to be watching for.

While JavaScript frameworks can implement some solutions to mitigate this (the Ember community in particular has a couple of different addon solutions and I'm trying to work on it in the core framework), it's entirely possible that the solution would be better handled in assistive technology.

Is there any way I could help? I'd like to be part of the solution if at all possible.

@jmn90
Copy link

jmn90 commented Mar 7, 2019

I also have a similar issue when the focus goes from a button to a section or button that was hidden. The focus goes to the right element, but NVDA never read the content. I tested with chromeVox and it works.

https://codepen.io/jmnoeltink/pen/BbppOm

@Adriani90
Copy link
Collaborator

cc: @jcsteh

@Adriani90
Copy link
Collaborator

This is still reproducible in NVDA 2019.1 anf Firefox 66.0.1 as well as Google Chrome 73.

@catamphetamine
Copy link

@haltersweb That's a good showcase app.
We implemented your idea in a workaround in our React app.
So, the workaround is to have an aria-live region outside of the current SPA "page" content.
Example:

<div id="page-loading-status-announcement" role="status" aria-live="assertive"/>

<main>
  ...
</main>

And then on each subsequent navigation it should:

  • document.getElementById('page-loading-status-announcement').textContent = 'New page is being loaded' on before loading new page has started.
  • document.getElementById('page-loading-status-announcement').textContent = '' after loading new page has ended (but not rendered yet, for example) — clears the announcement status (just to keep things consistent).
  • Waits for the new page to render.
  • document.getElementById('page-loading-status-announcement').textContent = 'New page content has been loaded'
  • setTimeout(() => document.getElementById('page-loading-status-announcement').textContent = '', 100) — clears the announcement status for the next state machine cycle.
  • Focus the new page content if not already auto-focused something (for example, some "autofocused" input field): if (document.activeElement === document.body) { document.querySelector('main').focus() }.
#page-loading-status-announcement
  position: absolute
  z-index: -1
  opacity: 0

@MIKOLAJW197
Copy link

Did anyone find some workaround? Currently I am working on some project (SPA) where I
reproduced this issue.

@chintan97
Copy link

Did anyone find the solution? Still facing the same issue. The element is getting focused but not read out by NVDA.

@carsonpowers
Copy link

Seeing the same issue; NVDA will read and recognize child elements, but shift-tabbing into the parent element will cause NVDA to ignore it. Tabbing onto the same parent element from an element that exists previous to it works, however.

@rpearce
Copy link

rpearce commented Sep 21, 2022

I run into this issue all the time with aria-hidden="true" elements that aren't read when turned to aria-hidden="false" and are programmatically focused on, and here's what I find works for me:

  1. Set aria-hidden="false" to everything that should be aria-hidden="true"
  2. Once the page loads or your component "mounts", set those ones that should be hidden to aria-hidden="true"

Doing this allows me to trick NVDA into registering the elements when they are loaded, and then I subsequently hide them. It's a pretty awful workaround, but it's something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment