add(a11y): Focus not obscured (WCAG 2.2 SC 2.4.11 + 2.4.12)#113
Merged
Conversation
The last WCAG 2.2 gap. Cross-checking all nine new 2.2 success criteria against the corpus: 2.5.7, 2.5.8, 3.2.6, 3.3.7, 3.3.8 and 3.3.9 all have pages; 2.4.11 had one sentence on focus-indicators; 2.4.12 appeared nowhere in src/. Follows the one-page-per-SC pattern of #91 (dragging-movements) and #92 (consistent-help), and pairs the AA and AAA variants on one page the way accessible-authentication already pairs 3.3.8 with 3.3.9. Why it is a separate page rather than a paragraph on focus-indicators: they fail independently and the fixes live in different places. 2.4.7 asks whether you drew a focus indicator. 2.4.11 asks whether anything is sitting on top of the one you drew. A site can ship an immaculate ring and still fail the moment Tab scrolls a control under a sticky header — the ring renders perfectly, it is just underneath something, and the remedy is scroll-padding on the scroll container, not a focus style. Auditable outcome, per the scope rule: tab through the page and watch whether the focused control disappears. Externally checkable, no source access needed. Status `recommended`, not `required`: 2.4.11 is Level AA, but the platform contract does not break without it. Matches dragging-movements and consistent-help, both AA and both recommended. focus-indicators now hands the topic off instead of half-covering it, and drops its 2.4.11 citation (the new page owns it). Its 1.4.11 citation is added, which is what the existing "3:1 against the adjacent colour" line was already asserting without a source behind it. Wired both ways into focus-indicators, keyboard-navigation, inert-attribute and cookie-consent. Changelog entry, OG images (new page + the 3 count-driven ones), and sign:skill 163 -> 164 pages included. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying specification-website with
|
| Latest commit: |
33dbf32
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://653b5906.specification-website.pages.dev |
| Branch Preview URL: | https://standards-scan-focus-not-obs.specification-website.pages.dev |
jdevalk
marked this pull request as ready for review
July 17, 2026 06:43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
New page: Focus not obscured (
accessibility,recommended, order 55), covering WCAG 2.2 SC 2.4.11 Focus Not Obscured (Minimum) (Level AA) and SC 2.4.12 (Enhanced) (Level AAA).Plus:
focus-indicatorshands the topic off, reciprocalrelatedSlugson four pages, changelog entry, OG images,sign:skill163 → 164.Why now
This is the last WCAG 2.2 gap. Cross-checking all nine new 2.2 success criteria against the full corpus:
focus-indicatorssrc/entirelyIt follows the one-page-per-SC pattern established by #91 (dragging-movements) and #92 (consistent-help), and pairs the AA and AAA variants on a single page exactly as
accessible-authenticationalready pairs 3.3.8 with 3.3.9.Why a separate page, not a paragraph on focus-indicators
They fail independently, and the fixes live in different places.
2.4.7 asks whether you drew a focus indicator. 2.4.11 asks whether anything is sitting on top of the one you drew. A site can ship an immaculate three-pixel high-contrast ring and still fail 2.4.11 the moment Tab scrolls a link under a 64px sticky header. The ring is rendering perfectly — it is simply underneath something. The remedy is
scroll-padding-topon the scroll container, not a focus style. That's why WCAG 2.2 made it a separate criterion rather than a note on 2.4.7, and it's why it earns a separate page here.focus-indicatorspreviously compressed this into one sentence plus ascroll-marginbullet that was actually the wrong fix (scroll-marginis per-target and handles anchor jumps; it does nothing for Tab). It now hands the topic off.Scope rule check — auditable outcome
Per the "auditable website outcome, not build technique" rule: tab through the page and watch whether the focused control disappears behind a sticky element. Externally checkable, no source access required, and the "Why it matters" lands squarely on visitors — sighted keyboard users, switch-access and voice-control users — not on the developer.
Worth noting why this bug survives: screen reader users are unaffected (content is announced from under the banner just fine), and no automated checker catches it. It only surfaces when a sighted person tabs through and watches. That's the page's reason to exist.
Status justification
recommended, notrequired. 2.4.11 is Level AA, but the web platform contract does not break without it — per CLAUDE.md the bar forrequiredis "the platform breaks", and the default isrecommended. This matchesdragging-movements(2.5.7, AA) andconsistent-help(3.2.6, AA), both AA and bothrecommended.Sources
scroll-padding— canonical path resolved via the MDN MCP server per CONTRIBUTING, not hand-written.Both exceptions (user-movable content, user-opened content) are taken from the normative notes rather than paraphrased from memory.
One drive-by correction, and one thing I did not do
Added a
1.4.11 Non-text Contrastcitation tofocus-indicators. Its existing "3:1 against the adjacent colour … (1.4.11)" line had no source behind it. That line is correct — I checked, because it initially looked like a misattribution of 2.4.13's requirement. It isn't: 1.4.11 genuinely is the adjacent-contrast rule.Left alone, flagged for follow-up: 2.4.13's own contrast test — 3:1 between the same pixels in the focused and unfocused states — is stated nowhere on the site.
focus-indicatorshas 2.4.13's 2px-area half but not its contrast half, and W3C explicitly distinguishes the two ("this differs from Non-text Contrast criteria, which measure adjacent contrast"). That's a real omission but a separate topic, so it isn't in this PR.Verification
npm run buildpasses — 164 pages indexed./llms.txt,/checklist/,/spec/accessibility/,sitemap-accessibility.xml, the.mdendpoint, and the/okf/bundle.npm run assetsrun; staged the new OG image plus the count-drivenog-default.png,og/checklist.png,og/spec.png,og/spec/accessibility.png. All other images byte-identical, as the deterministic generator promises.npm run sign:skillrun — 163 → 164 pages, digest recomputed; pre-commit drift check passes.format:checkclean.Note:
npm run assetsalso re-vendoredpublic/vendor/purify.min.js, which I deliberately excluded from this commit — dompurify was bumped to 3.4.12 in #100 but the vendored copy was never regenerated, so it's drifted. That's a real (if minor) finding, but a vendored security asset shouldn't ride along in a spec-page PR. Flagging separately.🤖 Generated with Claude Code