Repository navigation
Make all focus rings consistent #15139
Description
The problem
Quarto's HTML output has no single definition of keyboard focus. Controls use four different indicators:
- Browser ring: body links, sidebar links, and most buttons (some through
outline: revert, Restore keyboard focus indicator on bare .btn buttons #14785). 2px solid currentColoroutline: sidebar section toggles (quarto-nav.scss#L412-L418, Make website sidebar section toggles keyboard-operable buttons #14826).- Bootstrap's halo, a 4px
box-shadowof$primaryat 25% opacity, withoutline: 0: every.nav-link(navbar, "On this page", tabsets) and the listing sort, filter, and pagination controls (_nav.scss#L51-L54). - A 1px
box-shadow, withoutline: none: the search input and the search Cancel button (quarto-search.scss#L117-L134).
The two box-shadow indicators also lack contrast. They fail the 3:1 minimum of WCAG 1.4.11 in every case I measured:
| Control | Background | Contrast |
|---|---|---|
| Navbar item, default theme | navbar #517699 |
1.01:1 |
| "On this page" link, tab, listing controls | page #ffffff |
1.41:1 |
| Search input | page #ffffff |
2.42:1 |
Forced-colors mode removes box-shadow, so these controls then have no focus indicator at all (WCAG 2.4.7).
Proposal: one focus ring
I think Quarto should use one focus ring for every focusable element, defined in one place.
The first step is to turn off Bootstrap's halos at the source, with Sass defaults:
/*-- scss:defaults --*/
$focus-ring-box-shadow: none;
$form-select-focus-box-shadow: none;
$btn-focus-width: 0;Then one global :focus-visible rule can replace Quarto's per-control focus rules: the sidebar toggle rule, the #14785 outline: revert, and the outline: none rules in quarto-search.scss.
What the ring looks like is still open. For example, it can be the browser's own ring, or a ring that Quarto defines with good contrast in every theme. I will investigate the options in the PR.
I measured the indicators above on renders from Quarto 1.11.6, in Chromium 151 and WebKit 26.5 (Playwright 1.62). AI tools helped with this investigation, grounded in a local clone of quarto-cli at v1.11.6.
Activity