You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
a11y: dark-mode vs light-mode button violates axe-core #13463
Some notes on the shape of this control, from testing the toggle across formats with axe and the Chrome accessibility tree.
Current shape
All three places Quarto creates the toggle render essentially the same control — a link that acts as a button, with a CSS-drawn icon and (in two of the three) no text alternative:
Plain HTML documents with a light/dark theme pair, and single-page dashboards (toggle floats top-right)
❌ none
Multi-page dashboards (toggle in the dashboard navbar)
❌ none
For a screen-reader user this misses on all three prongs of WCAG 4.1.2 Name, Role, Value, not just the reported name:
Name — empty in the document and dashboard variants: announced as just "link" (the axe link-name failure filed here, also 2.4.4).
Role — announced as a link but behaves as a button; in particular Space doesn't activate it (links respond to Enter only).
State — which mode is active is conveyed only by swapping the bi-toggle-off/bi-toggle-on icon via CSS background-image, which never reaches the accessibility tree. A non-sighted user gets no indication of the current mode before activating, and no feedback afterwards — the theme swap is silent.
Suggested shape
The control is a binary on/off, and its visual is already a switch glyph, so the WAI-ARIA APG switch pattern is the natural fit:
<buttontype="button" role="switch" aria-checked="false"
aria-label="Toggle dark mode"
class="quarto-color-scheme-toggle …"><iclass="bi"></i></button>
with aria-checked kept in sync with the active mode ("true" when dark is on). This yields, in the same three contexts:
announced as "Toggle dark mode, switch, off/on" — name, role, and current state all conveyed;
the state change is announced when the user activates it;
Space and Enter both work, matching what the announced role promises.
Two notes from the APG guidance: the label should stay static (not flip to "switch to light mode" — the aria-checked state carries the changing part, and screen readers compose label + state), and the existing localized toggle-dark-mode string already used on the website variant fits as-is.
The reader-mode toggle shares the same link-as-button shape and would benefit from the same pattern, though it's beyond what this issue reports.
I verified the current behavior and the suggested shape with axe-core and the Chrome accessibility tree, AI-assisted and grounded in a local clone of this repo (per CONTRIBUTING.md).
Activity
cwickham commentedon Jul 17, 2026
Some notes on the shape of this control, from testing the toggle across formats with axe and the Chrome accessibility tree.
Current shape
All three places Quarto creates the toggle render essentially the same control — a link that acts as a button, with a CSS-drawn icon and (in two of the three) no text alternative:
Where each variant appears:
title="Toggle dark mode"For a screen-reader user this misses on all three prongs of WCAG 4.1.2 Name, Role, Value, not just the reported name:
link-namefailure filed here, also 2.4.4).bi-toggle-off/bi-toggle-onicon via CSSbackground-image, which never reaches the accessibility tree. A non-sighted user gets no indication of the current mode before activating, and no feedback afterwards — the theme swap is silent.Suggested shape
The control is a binary on/off, and its visual is already a switch glyph, so the WAI-ARIA APG switch pattern is the natural fit:
with
aria-checkedkept in sync with the active mode ("true"when dark is on). This yields, in the same three contexts:Two notes from the APG guidance: the label should stay static (not flip to "switch to light mode" — the
aria-checkedstate carries the changing part, and screen readers compose label + state), and the existing localizedtoggle-dark-modestring already used on the website variant fits as-is.The reader-mode toggle shares the same link-as-button shape and would benefit from the same pattern, though it's beyond what this issue reports.
I verified the current behavior and the suggested shape with axe-core and the Chrome accessibility tree, AI-assisted and grounded in a local clone of this repo (per CONTRIBUTING.md).
Update Playwright specs for color-scheme toggle button markup (#13463)
Note CSS selector change for color-scheme toggle in changelog (#13463)
Put the fallback color-scheme toggle in a landmark (#13463)
Name the navbar tool in the color-scheme toggle fixture (#13463)
Make dark/light mode toggle an accessible switch (quarto-dev#14739)