quarto-dev / quarto-dev/quarto-cli

a11y: RevealJS/Dashboard axe report scroll region lacks keyboard focus (scrollable-region-focusable)

Open Beginner friendly
#14,710 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

accessibility bug
Dominant language
JavaScript
Stars
6k
Forks
458
Avg merge
1d 9h
Merged PRs (30d)
41

Description

Found while adding automated Playwright self-scan coverage for the axe accessibility-checker's own report chrome (it audits the page, then injects a report UI that never gets audited itself unless a test scans it directly).

axe rule: scrollable-region-focusable · impact: serious · tag: wcag2a (2.1.1, 2.1.3)
Targets: the RevealJS report slide (section.quarto-axe-report-slide) and the Dashboard offcanvas body (.offcanvas-body inside #quarto-axe-offcanvas).

When the report grows past its container's height, both the reveal report slide and the dashboard offcanvas body become scrollable (overflow-y: auto), but neither element nor any descendant is keyboard-focusable, so keyboard-only users can't reach the rest of the violations.

The HTML overlay variant already handles this case:

https://github.com/quarto-dev/quarto-cli/blob/13b7e598805cb63b385be5e9bc3fa96d8fd7bb3b/src/resources/formats/html/axe/axe-check.js#L346-L358

The comment there reasons the reveal/dashboard variants don't need the same tab stop because "they don't scroll the report element itself" — true of the inner .quarto-axe-report, but the scrolling ancestor (the reveal slide / .offcanvas-body) is a different element the comment doesn't account for:

https://github.com/quarto-dev/quarto-cli/blob/13b7e598805cb63b385be5e9bc3fa96d8fd7bb3b/src/resources/formats/html/axe/axe-check.js#L360-L387
https://github.com/quarto-dev/quarto-cli/blob/13b7e598805cb63b385be5e9bc3fa96d8fd7bb3b/src/resources/formats/html/axe/axe-check.js#L389-L419

Confirmed directly with axe-core on an overflowing report in both formats: reveal's report slide (scrollHeight 901 vs clientHeight 700) and dashboard's offcanvas body (scrollHeight 774 vs clientHeight 658 — this one overflows even with a small, default-sized report) both get flagged.

We could mirror the overlay's fix — tabIndex = 0 / role="region" / aria-label on the scrolling ancestor in each case (the reveal <section> and the offcanvas body <div>), and correct the now-inaccurate comment above.

Related to #14378 (same axe rule, different target — document code blocks rather than the checker's own report UI). Part of #8706.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/resources/formats/html/axe/axe-check.js, reading the existing overlay handling and the RevealJS and Dashboard branches linked in the issue. Check the generated report slide and #quarto-axe-offcanvas .offcanvas-body with the Playwright self-scan or axe-core. Done means both scrolling ancestors are keyboard reachable and no scrollable-region-focusable violations remain, with the outdated comment corrected.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, playwright
Domain
accessibility, testing-qa
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
84/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.