Make WordPress Core

Opened 6 weeks ago

Last modified 4 weeks ago

#65746 new defect (bug)

Prevent unnecessary announcements for screen readers in the various themes and media browsers

Reported by: afercia Owned by:
Priority: normal Milestone: 7.2
Component: Administration Version:
Severity: normal Keywords:
Cc: Focuses: accessibility

Description

WordPress uses some modal dialogs to display collections of Themes and Media. The code name for these tools is 'browsers', as they allow to browse (navigate) the related collections.

#63760 / https://github.com/WordPress/wordpress-develop/pull/11560 introduces some improvements for screen readers announcements related to the currently displayed Theme or Media.

There's still room for improvements. Basically, in these places in the admin:

Installed themes:
/wp-admin/themes.php

Theme installer:
/wp-admin/theme-install.php?browse=popular

Customizer theme preview (click the 'Change' button and then previwe the themes):
/wp-admin/customize.php?return=%2Fwp-admin%2Fthemes.php

Media grid:
/wp-admin/upload.php

from a user persepctive, the pattern for browsing the collections is similar.

  • A modal dialog opens showing a Theme or Media details.
  • Users can navigate to the next or previous item by clicking the Next and Previous buttons or by using keyboard shortcuts.
  • For screen readers, the currently displayed item name is announced.

I'd like to propose to improve a couple things:

1
Make sure the navigation mechanism is consistent across all these UIs. For example, there are subtle differences about where focus is placed after navigating to another item, which also impacts announcements for screen readers.

2
When navigating to another item, focus is placed (or it is supposed to be) on the most appropriate Next or Previous button. This is necessary because in most of the cases the entire content of the modal dialog is re-rendered. Placing focus on a specific button prevents a focus loss.

However, when one of the navigation buttons receives focus, screen readers will announce the newly focused element. This is standard screen readers behavior.

When the button is announced, it often delays or conflicts with other important announcements, for example the name of the currently displayed item. The announcement of the button is really unnecessary for screen reader users. It just adds undesired noise. We should try to find a way to prevent it and provide users with only the most useful information.

Change History (4)

This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.


5 weeks ago

#2 @joedolson
5 weeks ago

  • Milestone Awaiting Review7.2

#3 @sukhendu2002
5 weeks ago

Tested against current trunk. I can confirm the underlying focus/live-region conflict remains, although behavior differs between interfaces:

  • Theme Installer: focus returns to the recreated Previous/Next button, followed by the debounced Theme details: %s live-region update.
  • Customizer: similarly focuses the recreated navigation button before the live-region update.
  • Media Grid: explicitly focuses the navigation button before announcing Viewing media item: %s.
  • Installed Themes: differs from the above; focus settles on the recreated role="dialog" container rather than the navigation button.

Testing with VoiceOver and Safari confirmed the focused-control announcement (for example, “Next theme, button”). Preview iframe loading could then interrupt or obscure the delayed live-region announcement. Browser instrumentation confirmed that the live-region text itself is updated correctly, so this appears to be a focus/announcement sequencing problem rather than a missing DOM update.

Hiding the button label with aria-hidden, removing the screen-reader text, or changing its role would not be a safe fix because the focused control must retain an accessible name.

I have not prepared a patch because the intended focus behavior needs agreement first:

  1. Should focus remain on Previous/Next to support repeated activation?
  2. If not, should it move to the dialog or current item heading?
  3. Should pointer activation and Alt+Arrow navigation use different focus behavior?
  4. Could the navigation controls remain stable while only the content is rerendered?

#4 @khokansardar
4 weeks ago

I audited the four UIs on current trunk to pin down exactly where focus lands after navigating, since comment:3 notes the behaviour differs between them.

UI Focus target after prev/next Source
Theme installer .next-theme / .previous-theme src/js/_enqueues/wp/theme.js:575,606
Customizer .right / .left src/js/_enqueues/wp/customize/controls.js (nextTheme/previousTheme)
Media grid .left / .right via focusNavButton() src/js/media/views/frame/edit-attachments.js:241,258
Installed themes .theme-overlay (the role="dialog"), on a 100ms delay src/js/_enqueues/wp/theme.js:735 (containFocus)

So three of the four focus the navigation button and one focuses the dialog container. All four then fire the 500ms-debounced wp.a11y.speak() added in [62878]. This confirms comment:3.

On the four open questions in comment:3: Q4 ("could the navigation controls remain stable while only the content is rerendered?") looks like it dissolves Q1–Q3 rather than being an alternative to them. The button is announced only because it is destroyed and recreated, which forces the explicit .trigger('focus') calls above. If the Previous/Next controls survive the re-render, focus never moves, so:

  • there is no focused-control announcement to suppress, which is ticket item 2;
  • focus stays on the navigation button, so repeated activation keeps working (Q1);
  • "where should focus go instead" (Q2) and "should pointer and Alt+Arrow differ" (Q3) no longer need an answer, because focus does not go anywhere;
  • the live region is left as the only announcement, which is the desired outcome.

The cost is that it means restructuring the re-render in three separate Backbone view hierarchies (media modal, theme preview, customizer section), so it is not a small patch and it touches load-bearing code. Worth confirming that is the direction before anyone writes it.

Note: See TracTickets for help on using tickets.