standards-support icon indicating copy to clipboard operation
standards-support copied to clipboard

Need a means of suppressing speech output during focus transitions within a SPA

Open kloots opened this issue 9 months ago • 3 comments

Context

This is a feature request, born out of a use case from Slack.

Background

When transitioning focus between views in a single-page web app, focus will move to the <body> during the time between the previous view being removed from the DOM and the new view being rendered.

Consider the following example:

  1. Focus is within a section of the application.
  2. The user takes an action to navigate to a different view.
  3. The DOM for the view the user is navigating from is torn down, resulting in...
  4. The browser moves focus to the <body>. The screen reader announces the title of the window.
  5. The DOM for the view the user is navigation to is rendered.
  6. An element within the view is focused and the screen reader announces the currently focused element, its label, state, etc.

So, it is step 4 that is problematic. Having the screen reader announce the title of the window with every navigation is undesirable as demonstrated in this Codepen example.

In Slack, to mitigate this verbosity during a focus transition we currently employ a two step solution:

First we move focus to a temporary element within the application; one that will:

  1. Not produce any speech
  2. Not trigger the screen reader into browse mode.
<div role="application" aria-label="&nbsp;&nbsp;" tabindex="-1" aria-roledescription="&nbsp;&nbsp;">

This is an effective solution as demonstrated in this Codepen example.

If the loading of the next view is taking longer than some predetermined number of milliseconds we then move focus to a progress bar that functions as a loading indicator.

In most cases the loading of the new view is fast enough that we don't need to focus the loading indicator, meaning in most cases there is no unwanted speech output as we transition focus between views.

Proposed Solution

While the solution we have in place works, a standard solution would be preferable. aria-busy seems like it could be the right tool for the job, specifically we could apply aria-busy="true" to the view container and focus it as we transition from one view to another. However, this will result in "busy" being announced immediately, which is arguably also too verbose/unnecessary for view transitions that only take a few seconds as demonstrated in this Codepen example.

One idea was to have JAWS defer the announcement of "busy" until some number of milliseconds. This way the user would only hear busy if the focus transition is taking long enough to signal to the user that they need to wait.

kloots avatar Apr 25 '25 04:04 kloots

For reference, I opened a discussion on this topic on the W3C ARIA github as issue 2525.

kloots avatar May 06 '25 21:05 kloots

Thanks. Was looking for this very thing.

edcourtney74 avatar May 09 '25 17:05 edcourtney74

I think aria-busy is the right solution here. We recently dealt with a similar situation in Windows Explorer. In that case, Windows was displaying "working" every time you changed folders. This was extremely verbose and we had a number of users complaining. Our solution was to only speak "working" if the time it was shown exceeded a threshold (I think around a second right now). We can implement a delay on the announcement of busy. I will file an issue. One other wrinkle, braille users will need to have the message suppressed as well or there is undesirable flickering on the braille display.

BrettLewisVispero avatar Nov 20 '25 23:11 BrettLewisVispero