nvda icon indicating copy to clipboard operation
nvda copied to clipboard

NVDA doesn’t announce row headers on columns that precede the row header’s column

Open joelamyman opened this issue 1 month ago • 1 comments

Brief summary

When NVDA is announcing content in a column that precedes the row header, the contextual row header announcement will not be announced. This seems to be a bug, that affects both tables (using HTML elements) as well as ARIA grid patterns (using role="gridcell" and role="rowheader"). As the row header is not announced as expected, this can make it difficult to quickly understand the row that you are interacting with.

Steps to reproduce

  1. Open Firefox
  2. Navigate to https://cdpn.io/pen/debug/jEqXVvJ/1764e75bb1dde1dee6eb41b69407228c
  3. Press Tab until focus reaches the grid
  4. With focus on a cell in either the first or second column ("Actions" and "Availability" respectively), navigate to a different row by pressing the up or down arrow key
  5. Note that the row header (in this example, the item name) is not announced
  6. Move focus to the fourth or fifth column ("Who is picking up?" and "Price" respectively), then navigate to a different row by pressing the up or down arrow key
  7. Note that the row header (in this example, the item name) is now announced

Actual behavior

NVDA speech:

Home link
tab Manage your order table Row actions for Cushioned work socks not selected To interact with controls in the cell, press Enter. row 2 Actions column 1 right arrow In store not selected row 2 Availability column 2 down arrow Mixed not selected row 3 Availability column 2 right arrow Patio furniture set row header not selected To interact with controls in the cell, press Enter. row 3 Item column 3 right arrow Bruce Delete not selected To interact with controls in the cell, press Enter. Patio furniture set row 3 Who is picking up? column 4 right arrow $897.05 not selected Patio furniture set row 3 Price column 5 up arrow $8.62 not selected Cushioned work socks row 2 Price column 5

Expected behavior

Row headers should be announced when changing rows even in columns that precede the row header. For example:

Manage your order table Row actions for Cushioned work socks not selected To interact with controls in the cell, press Enter. Cushioned work socks row 2 Actions column 1 right arrow In store not selected Cushioned work socks row 2 Availability column 2 down arrow Mixed not selected Patio furniture set row 3 Availability column 2 right arrow Patio furniture set row header not selected To interact with controls in the cell, press Enter. row 3 Item column 3

NVDA logs, crash dumps and other attachments

No response

NVDA type

installed copy

NVDA version

2025.3.2 (2025.3.2.53588)

Have you tried any other versions of NVDA? If so, please report their behaviors.

  • NVDA 2025.3.1: issue is consistent

Windows version

Windows 11 Version 10.0.26100 Build 26100

Name and version of other software in use when reproducing the issue

Firefox version: 146.0 (64-bit)

Other information about your system

No response

Does the issue still occur after restarting your computer?

I have restarted my computer and the issue still occurs

If NVDA add-ons are disabled, is your problem still occurring?

I have restarted NVDA with add-ons disabled and the issue still occurs

Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?

I have run the COM Registration Fixing Tool and the issue still occurs

joelamyman avatar Dec 09 '25 15:12 joelamyman

Per the HTML Standard § 4.9.10 The th element:

The th element may have a scope content attribute specified.

The scope attribute is an enumerated attribute with the following keywords and states:

Keyword State Brief description
row Row The header cell applies to some of the subsequent cells in the same row(s).
col Column The header cell applies to some of the subsequent cells in the same column(s).

And per Accessible Rich Internet Applications (WAI-ARIA) 1.2 § 5.4 Definition of Roles ¶ rowheader role:

The rowheader role can be used to identify a cell as a header for a row in a table, grid, or treegrid. The rowheader establishes a relationship between it and all cells in the corresponding row. It is a structural equivalent to setting scope="row" on an HTML th element.

According to my reading:

  1. The HTML <th> element explicitly only applies to subsequent cells in its row or column (according to its scope).
  2. The ARIA rowheader role is supposed to apply to all cells/gridcells in the owning row.

This is kind of inconsistent. What's more, I don't know if we have a good way of determining where the headers are coming from (ARIA or pure HTML).

SaschaCowley avatar Dec 10 '25 00:12 SaschaCowley

The ARIA spec is unclear on whether subsequent means "to the right of". We would need some clarification on standards for ATs and what the community expects.

Converting to a discussion.

gerald-hartig avatar Dec 16 '25 00:12 gerald-hartig