Repository navigation
Description
Follow-up to #13491 and #13910.
What happened
In NVDA browse mode, the sidebar thread list is not announced as a list, and the Snooze and Settle buttons on each row cannot be reached. Before #13491, NVDA reached them.
Diagnosis
Each thread row is a <div role="button"> with real buttons nested inside it: Snooze, Settle, Un-settle, Wake, Unpin, Dismiss Woke, and the PR badge. Draft rows nest Discard.
- fix(accessibility): correct control announcements and sidebar traversal #13491 set
role="presentation"on the thread<ul>, which removes list semantics and NVDA's L and I navigation. It also added anaria-labelto each row. NVDA's browse mode does not render the children of a button that has an author-supplied name (NVDA source), so the nested buttons disappear. - Removing the label (fix(web): restore sidebar thread list and row actions for NVDA #13910) brings them back for NVDA only. WebKit leaves every descendant of
role="button"out of the accessibility tree, focusable or not (WebKit source). VoiceOver in Safari likely cannot reach them with or without the label. This comes from the source, not a VoiceOver test. - ARIA defines the children of a button as presentational (WAI-ARIA). The pattern fails ACT rule 307n5z and axe's
nested-interactive.
Whether VoiceOver makes users interact with a list depends on their web navigation setting. Lists require interaction under "Grouping items" but not under "DOM order" (Apple).
Steps to reproduce
- On Windows, run NVDA and open T3 Code (desktop, or web in Chrome or Firefox).
- In browse mode, press L to move to the thread list.
- Arrow through an active thread row.
Environment
main @ de251fc, Windows 11, latest stable NVDA and Chrome.
Workaround
The row's context menu (Applications key) includes Settle, Snooze, and Pin.
Proposed fix
Give each row one native button that opens the thread, named by its title. Put the row actions in the same <li> as siblings of that button, not inside it, and keep role="list". The button fills the row behind its content, so nothing changes visually: layout, colors, and the focus ring match main in Chromium.
In Sarah Higley's secondary actions study, buttons placed next to a tab worked in JAWS, NVDA, and VoiceOver. The same buttons nested inside the tab failed.
Branch: akj:fix/sidebar-row-sibling-actions (diff). It is verified with NVDA. Before a PR, it needs VoiceOver checks on macOS in Safari and Chrome, under both DOM order and Grouping items navigation.
Activity
juliusmarminge commentedon Sep 27, 2026
Triage
Confirmed on
mainatde251fc. This is not a duplicate, and the partial fix in #13910 never merged, so the default sidebar still has both pieces of the #13491 regression.The thread list is a
<ul role="presentation">. Card, slim, and draft rows are each a<div role="button">whose accessible name istitle, status, project. Snooze, Settle, Un-settle, Wake, Unpin, Dismiss Woke, Discard, and the PR badge are real buttons or links inside that button. That matches the NVDA browse-mode failure. Search results are a separate case: arole="option"with a label and no nested actions. Those labels should stay.Removing the row label is not sufficient. ARIA treats a button’s children as presentational, and WebKit omits every descendant of
role="button"from the accessibility tree whether or not the button has an author-supplied name. Each row needs one native button that opens it, with the actions as siblings in the same<li>, and the list role restored.akj:fix/sidebar-row-sibling-actionsis that change. From the source, keyboard activation of the primary button still bubbles to the row click handler, and the action buttons already stop propagation. Please open it as a PR.VoiceOver is the merge check, which is why #13910 was held. #13491 set
role="presentation"because an exposed list was a VoiceOver interaction boundary. On the PR, please include the Safari and Chrome pass under both DOM order and Grouping items, and specifically:aria-hidden.inset-0, negative z-index). You already verified that with NVDA in Chromium; VoiceOver may treat a covered control differently.Until this lands, the row context menu is how to reach Settle, Snooze, and Pin.
juliusmarminge commentedon Oct 22, 2026
Existing fix: #13962, already taken over by a maintainer. No competing PR opened. Its comments record passing contributor NVDA checks; the remaining gate is VoiceOver in Safari and Chrome under both DOM order and Grouping items. This triage host is Linux and has neither NVDA nor Safari, so native screen-reader reproduction was not run. Leaving this issue open for the existing fix and native verification.