fix(docs): the phone nav toggle needs a keyboard, not a mouse
A regression the previous commit introduced, found in review. The checkbox driving the collapsed nav carried `hidden`, which is `display:none`, which removes it from the tab order AND from the accessibility tree. A <label> is not focusable on its own -- the checkbox it labels is what carries focus -- so at <=900px the navigation could be clicked and reached no other way, and the accessibility snapshot contained neither the checkbox nor any of the 25 links. The toggle is now visually hidden but focusable at narrow widths, and display:none at wide ones. Keeping display:none on the wide side matters: merely un-hiding it puts focus on an invisible control whose label is display:none, which is its own wart. Measured at 390, 900, 901 and 1280, because the regression lives on one side of a media query. At 390 and 900 the tab order is brand -> navtoggle, the toggle is focusable, the a11y tree carries a checkbox node, and Space takes visible nav links 1 -> 26. At 901 and 1280 the toggle is display:none, not focusable, absent from the a11y tree, and tab runs straight through the 26 links -- desktop identical to before. 0 of 23 pages scroll horizontally at 320, 390 and 1280, so the absolutely-positioned 1px input introduces nothing. WHAT IS WORTH MORE THAN THE FIX, and why doc-site.md gains a paragraph rather than the code gaining a comment: my probe for the previous commit counted VISIBLE nav links. That answers "does operating the toggle reveal the links" -- correct and complete for a mouse -- and is silent on whether any non-mouse route exists. It could not have seen this, however sharp the visibility instrument was. Last round's lesson was that a measurement which cannot distinguish the two states is not a measurement; this round adds the half it was missing: a measurement of the wrong PROPERTY is not a measurement either. checkVisibility fixed the visibility instrument; it does not turn a visibility count into an operability check. The instrument here is tab order, .focus() and the accessibility snapshot. Gates: 1378 rust, 26 node --test, 16 playwright (3 skipped, webkit OPFS), all three check-comment-runs modes, 3462 site links / 0 broken, 0 nested anchors, 0 of 23 pages overflow at 320/390/1280. improvise-djoo Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -220,3 +220,56 @@ the first guess was wrong: `getBoundingClientRect` reported every element
|
||||
inside the viewport, because the text overflows its box without widening it.
|
||||
Only `scrollWidth` per element names the culprit. Measure the property that
|
||||
actually overflowed rather than the one that usually does.
|
||||
|
||||
## 7. The phone nav is a checkbox, and that is not arbitrary
|
||||
|
||||
At phone width the sidebar's 25 links stacked above the content, so every page
|
||||
opened on roughly 1500px of nav. The wall was not inherited: **all of this CSS
|
||||
is new**, so it shipped for the first time with the site, which is the test for
|
||||
whether a defect is pre-existing and the one most easily got wrong in the
|
||||
direction of declining work you introduced.
|
||||
|
||||
`<details>` is the obvious control and it is **wrong here**, for a reason no
|
||||
spec-level reading predicts. The sidebar layout has to force the disclosure
|
||||
*open* at wide widths, and a closed `<details>` hides its content through
|
||||
`::details-content` — which `display` cannot override. Measured in Chromium,
|
||||
the desktop sidebar came out collapsed to a single link with its toggle also
|
||||
hidden: unusable, and in the half nobody would think to re-check after a
|
||||
phone-only change. A hidden checkbox plus a `<label>` puts the hiding in *our*
|
||||
media query, so forcing it open is ordinary cascade. Anyone reading the markup
|
||||
will see a checkbox where `<details>` obviously belongs; this paragraph is why
|
||||
it must not be tidied into one.
|
||||
|
||||
**And the first probe of the fix could not see the difference.** Counting nav
|
||||
links whose `getBoundingClientRect().height > 0` reported **26 visible in both
|
||||
the collapsed and the expanded state**, because Chrome reports a height for
|
||||
`content-visibility`-hidden children — so it would have passed the broken
|
||||
`<details>` build. `checkVisibility({contentVisibilityAuto: true,
|
||||
visibilityProperty: true})` discriminates.
|
||||
|
||||
That is the same instrument failing twice: §6's overflow fix also measured
|
||||
clean by `getBoundingClientRect` while the page still scrolled. **A measurement
|
||||
that cannot distinguish the two states is not a measurement** — the repo's
|
||||
signature defect, a test that passes while the thing it names is broken,
|
||||
arriving through the instrument rather than through the assertion. Before
|
||||
trusting a browser measurement, injure the thing being measured and check the
|
||||
number moves.
|
||||
|
||||
**And the fix's own probe had the same shape one level up.** Counting *visible*
|
||||
nav links answers "does operating the toggle reveal the links" — correct and
|
||||
complete for a mouse — and is silent on whether any non-mouse route exists. The
|
||||
first version of the checkbox carried `hidden`, which is `display:none`, which
|
||||
removes it from the tab order *and* from the accessibility tree: the label is
|
||||
not focusable on its own, so at ≤900px the navigation could be clicked and
|
||||
reached no other way, and the accessibility snapshot contained neither the
|
||||
checkbox nor any of the 25 links. A visibility count cannot see that, however
|
||||
sharp the visibility instrument. The toggle is therefore visually hidden but
|
||||
focusable at narrow widths and `display:none` at wide ones, and the check is
|
||||
tab order, `.focus()` and the accessibility snapshot — measured at 390, 900,
|
||||
901 and 1280, because the regression lives on one side of a media query.
|
||||
|
||||
So the rule from §6 has a second half: **a measurement of the wrong property is
|
||||
not a measurement either, however precise it is.** `checkVisibility` fixed the
|
||||
visibility instrument; it does not turn a visibility count into an operability
|
||||
check. Ask what the defect would *do* to a user, then pick the instrument that
|
||||
observes that.
|
||||
|
||||
Reference in New Issue
Block a user