Repository navigation
feat: restore visible keyboard focus via :focus-visible (#139) - #182
Merged
Merged
Conversation
Replace the outline:none + subtle 1px box-shadow :focus rule with a visible :focus-visible treatment on all interactive elements (a, button, input, select, textarea, summary, [tabindex]). The new rule applies outline: 2px solid var(--color-primary); outline-offset: 2px on keyboard focus only — no mouse-click ring. Form controls retain their border-color + box-shadow signal, switched to :focus-visible so it no longer fires on mouse click (fixes a latent bug). :focus-visible is supported across the entire browserslist (Safari 15.4+, iOS 15.4+, latest Chrome/Firefox/Edge), so no :focus fallback is needed. Resolve the a11y baseline findings tagged "fix in v1 -> #139": - .icon-only buttons get aria-label="Search" + img alt="Search" (button-name + image-alt) - .brand link with decorative img gets aria-label="Brand" (link-name) Add test/vrt/keyboard-focus.spec.js (12 tests: 9 computed-style :focus-visible assertions on Tab navigation + 3 focus-state VRT baselines). Replace the observation-only a11y-keyboard.spec.js. Wire keyboard-focus.spec.js into test:vrt; remove the stale a11y-keyboard.spec.js reference from test:a11y. Size: 3326 -> 3372 gzip bytes (+46, within 4096 ceiling). Baseline bumped in baselines/size-baseline.json with rationale. Local: yarn build PASS; yarn test:vrt 100 passed; yarn test:a11y 4 passed (button-name/image-alt/link-name gone); yarn test:api 5 passed.
Generated from CI failure artifacts on PR #182 (run 31321260633). All 3 failures were 'snapshot doesn't exist, writing actual' — no real visual diffs. The actuals are the Linux Chromium (ubuntu-latest) focus-state renderings and are the required merge evidence per test/vrt/README.md platform policy.
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.
Card: #139 — restore visible keyboard focus via :focus-visible
Closes #139
Summary
Restores visible keyboard focus by replacing the
outline: none+ subtle 1px box-shadow:focusrule with a visible:focus-visibletreatment on all interactive elements. Also resolves the a11y baseline findings (button-name, image-alt, link-name) tagged "fix in v1 -> #139" via fixture markup fixes.This is the first production CSS change in v1 that touches shared form CSS. Per
AGENTS.md, owner review is required for public CSS API changes.Changes
Production CSS (
src/_form.css)outline: none+border-color+box-shadowoninput:not(...):focus, select:focus, textarea:focus(the root cause of invisible focus):focus-visiblerule ona, button, input, select, textarea, summary, [tabindex]withoutline: 2px solid var(--color-primary); outline-offset: 2px;:focus-visiblerule preservingborder-color+box-shadow(switched from:focusto:focus-visibleso it no longer fires on mouse click — fixes a latent bug):disabled, form-control rule after) to satisfy stylelintno-descending-specificitya11y fixture fixes
test/index.html:.icon-onlybutton getsaria-label="Search"+ imgalt="Search"test/components.html: two.icon-onlybuttons get the same fix;.brandlink with decorative img getsaria-label="Brand"Tests
test/vrt/keyboard-focus.spec.js(NEW, 12 tests): 9 computed-style:focus-visibleassertions on real Tab navigation + 3 focus-state VRT baselinestest/vrt/a11y-keyboard.spec.js(DELETED): was observation-only, replaced bykeyboard-focus.spec.jspackage.json:test:vrtincludeskeyboard-focus.spec.js;test:a11yremoves the stalea11y-keyboard.spec.jsreferencetest/vrt/README.md: documents the new spec and coverageSize baseline
baselines/size-baseline.json: 3326 → 3372 gzip bytes (+46, within 4096 ceiling) with rationaleBrowser support
:focus-visibleis supported across the entire browserslist::focus-visiblewas added in Safari 15.4)No
:focusfallback needed.Behavior change
By design,
:focus-visibleshows the outline on keyboard focus only, not mouse click. This is the intended UX improvement. Form controls retain their border-color + box-shadow signal, but only on keyboard focus (previously fired on mouse click too — a latent bug now fixed).Validation (local macOS)
yarn build: PASS, 3372 bytes (baseline 3372, ceiling 4096)yarn test:vrt: 100 passed (was 88; +12 new keyboard-focus tests)yarn test:a11y: 4 passed (button-name/image-alt/link-name gone; only deferred color-contrast/frame-title/scrollable-region-focusable remain)yarn test:api: 5 passed (185 selectors / 14 custom properties unchanged)git diff --check: cleanLinux baselines
The 3 focus-state VRT baselines are darwin-only (
-chromium-darwin.png). Linux-chromium-linux.pngbaselines will be generated from CI failure artifacts (same pattern as #180/#181) and added before merge.Scope
src/_form.css,dist/**,baselines/size-baseline.json,test/index.html,test/components.html,test/vrt/keyboard-focus.spec.js,test/vrt/a11y-keyboard.spec.js(deleted),test/vrt/snapshots/keyboard-focus.spec.js-snapshots/**,test/vrt/README.md,package.jsonsrc/_base.cssand other source partials,test/vrt/a11y-baseline.json(untouched — disappearing nodes auto-pass),playwright.config.js,.github/**,AGENTS.md,test/AGENTS.md,PLAN.md, other VRT specsAGENTS.md