v3.1.0
Nothing measured this theme's own accessibility. The unit suite runs in jsdom, which has no
layout and no colours, and the sweep in
book-of-elementals deliberately audits the
<code-preview> iframes and excludes the pages around them — because those pages are this
theme's markup, and reporting them there would file this repo's bugs against that one. The
hole was exactly the shape of the chrome: the topbar, the drawer, the nav tree, the prose
styles and every contrast ratio in the palette.
Added
-
script/a11y— axe over the preview site, in Chromium. Each page as served, then with
everything that says it is closed opened, then with the search panel showing hits and
again showing its empty state. The document-level rules stay on, which is the opposite
call from the sibling sweep and for the opposite reason: a landmark, a skip link, a title
and alangare a fragment's business nowhere and this theme's business exactly.Two viewports, not one. The bar folds into a drawer below
40remand the sidebar
toggle only exists below60rem, so the markup a phone gets is markup a desktop never
renders. A sweep at one width audits half the theme and reports as though it did all of
it. Two themes as well, seeded throughlocalStoragebefore the page loads rather than
set on the document after: the boot script reads that key and the topbar switch seeds
itself from what it chose, so settingdata-themeby hand would audit a dark page with a
switch still reporting itself off — a disagreement the sweep would have introduced and
then measured.It also fails on an
aria-controls,aria-labelledby,aria-describedbyor
aria-activedescendantnaming an id no element has. axe will not decide that one — a
collapsed toggle may legitimately point at a panel not in the document yet — so a typo in
one otherwise fails no run anywhere. None are dangling today.Contrast axe cannot compute, over a pseudo element or under something overlapping it, is
printed by rule and by reason rather than guessed at. New devDependencies:axe-coreand
playwright-core— the same pair the sibling repo uses,playwright-corebeing the one
that ships no browser, sonpm cidoes not download one.It found 161 violations across four rules on the first run. They are the Fixed list
below, and CI now runs the sweep, so the count stays at nought. -
A skip link, first in the body of both layouts. Reaching the prose from a keyboard meant
tabbing the whole topbar first — brand,docspill, search, everysite.linksentry, the
GitHub link, the theme switch — and on a docs page the entire nav tree after it: every
heading of every section, on every page, before the one you asked for. That is
WCAG 2.4.1 Bypass Blocks,
and the sweep above did not catch it: axe'sbypassrule is satisfied by a<main>
landmark, which both layouts have had all along.Off-screen until focused rather than
display: none— a hidden element is out of the tab
order, which is the one thing this link cannot be. No script::focusis the keyboard
intent, and a pointer never reaches the link to see it.DOM change: both layouts gain
<a class="skip-link" href="#content">as the first child
of<body>, and<main class="content">gainsid="content"andtabindex="-1". A site
already using#contenthas a duplicate id to resolve. Thetabindexis what makes the
jump land: a fragment pointing at an element that cannot take focus moves the viewport and,
in Safari, leaves focus on<body>— so the next Tab goes back to the topbar the link just
skipped. CSS change:.content:focusdrops the focus ring with it, because the theme's
2px outline drawn around the whole column reads as breakage rather than as focus arriving.
Fixed
-
Syntax highlighting and admonition titles now meet AA, in both themes. The light code
scheme ran 2.8:1 to 4.0:1 on--bg-code— a set of hues chosen against each other rather
than against the surface behind them. Each is now the same hue darkened until it clears
4.5:1, keeping 75% to 92% of what it was, so the scheme still reads as itself. The dark
scheme was already 6.2:1 to 11.5:1 and is untouched.Admonitions were worse and failed at both ends, because
--admis one value doing three
jobs: the border, the 7% tint behind the title, and the title's own text. One mid-range hue
cannot be text on a white tint and text on a dark one —importantread at 1.8:1 in
light,cautionat 3.7:1 in dark. Light now takes a darkened set and dark keeps the
original where it already cleared. Yellow is the one that could not keep its face: nothing
about a 7%-tinted white leaves room for#fab005, soimportantis a dark gold in light
now. CSS change: the--admvalues, and a site overriding them should recheck its own. -
The dark code scheme reaches a reader whose dark mode came from the OS. The token
colours were under:root[data-theme="dark"]alone, while_base.scsssets its own tokens
under that andprefers-color-scheme. With the script blocked the attribute never lands,
so the surface went dark and the syntax colours stayed light — the one pairing neither set
had been measured against. Both now come from one mixin applied in both places. -
A code block and a wide table can be scrolled from the keyboard. Both scroll sideways
and neither could be reached without a pointer: nothing inside apretakes focus, since
the copy button is a sibling in the wrapper rather than a child. Both now take
tabindex="0". Unconditionally, not from a measurement — whether the content is wider than
the column is a question the viewport answers, and an answer taken once is wrong at the
first resize. DOM change:.prose preand.prose tablegaintabindex="0". -
The phone search field no longer leaves focus underneath itself. Opening it expands it
across the whole topbar, by design — but the brand, the nav toggle and the icon links stayed
in the tab order behind it, so tabbing out of the field put focus on a GitHub link no one
could see. That is WCAG 2.2's Focus Not Obscured (2.4.11), and it was a tap target too: axe
measured 1px of the nav toggle left uncovered. Everything the open field covers is now
visibility: hiddenfor as long as it covers it, which takes it out of the tab order and
the accessibility tree together. -
The heading permalink is not a tab stop on nothing. Poops writes it
aria-hidden="true"
and focusable, so a keyboard landed on it once per heading with nothing to announce. Fixed
at the source in poops, butpoopsis a peer at
>=2.0.0and the versions this theme supports include the ones that write it — so the
theme repairs it on load as well, and is measured green against a build that has not got
the fix. That patch goes when the peer floor rises past the fixed release.
Full Changelog: v3.0.1...v3.1.0