fix(anchor-menu): keep sticky menu keyboard-reachable at 200% zoom#1713
Open
juanmitriatti wants to merge 1 commit into
Open
fix(anchor-menu): keep sticky menu keyboard-reachable at 200% zoom#1713juanmitriatti wants to merge 1 commit into
juanmitriatti wants to merge 1 commit into
Conversation
The sticky behavior relocated the menu in the DOM (globalHeader.appendChild), which moved its focusable controls out of the keyboard tab order. At 200% desktop zoom (effective width < lg) the menu is a collapsed sticky bar, so forward Tab skipped it entirely and keyboard users could not reach it. Pin the menu in place with CSS (position: fixed; top: var(--uds-anchor-menu-top)) instead of moving the node, mirroring the unity-react-core AnchorMenu. The node never leaves its document position, so tab order is preserved. Attach/detach is now driven by a scroll threshold against the stored original offset rather than the live rect of a now-fixed element. Fixes WCAG 2.1.1 Keyboard (Level A) and 2.4.3 Focus Order (Level A). UDS-1638 / UDS-2160
Collaborator
|
Storybook deployed at https://unity-uds-staging.s3.us-west-2.amazonaws.com/pr-1713/index.html |
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.
Description
Problem. Across all pages with the anchor menu, zooming to 200% on desktop
made the menu unreachable by keyboard: tabbing through the page skipped the
anchor menu entirely, and the only way to reach it was to zoom back below 200%.
(Reported in the accessibility audit — UDS-1638 / UDS-2160.)
Root cause. The sticky behavior made the menu "stick" by physically
relocating the node in the DOM —
globalHeader.appendChild(navbar)inanchor-menu.js. Because tab order follows DOM order, attaching the menumoved its focusable controls from their in-content position to inside the
global header — i.e. earlier in the document than the user's current focus.
At 200% zoom the effective width drops below the
lgbreakpoint, so the menu isa collapsed sticky bar. As a keyboard user tabs down the page, the scrolling
that tabbing causes triggers the relocation, and the menu jumps to a point the
user has already passed. Forward
Tabthen never lands on it.Fix. Pin the menu in place with CSS instead of moving the node:
position: fixed; top: var(--uds-anchor-menu-top), where the JS sets--uds-anchor-menu-topto the global header's bottom offset. The node neverleaves its document position, so the tab order is preserved. Attach/detach is
now driven by a scroll threshold against the stored original offset (rather than
reading the live rect of an element that is
position: fixed). This mirrors thealready-accessible
unity-react-coreAnchorMenu, which has always positionedin place via the same CSS variable — so this also removes divergence between the
two implementations.
Fixes WCAG 2.1.1 Keyboard (Level A) and WCAG 2.4.3 Focus Order (Level A).
Why not just add a
tabindex?The element was never missing from the tab order, so
tabindexdoes not addressthis bug:
<button>withtabindex = 0and is fullyfocusable (verified). The problem was never focusability.
tabindex="-1"makes an element focusable only programmatically andremoves it from the sequential tab order — the opposite of what we need.
tabindex="0"is redundant here — the button is already in the tab order.tabindex(1+) is a WCAG anti-pattern and still wouldn't help,because the node is physically relocated regardless of its tabindex.
The defect is a DOM-order problem, not a focusability one: the menu node is
moved to before the user's current focus position while they tab, and no
tabindexvalue changes where a node sits in document order. The only realoptions are (a) don't move the node — position it in place with CSS (this PR),
or (b) keep the relocation and add focus-management hacks to compensate (fragile,
and it treats the symptom). This PR takes (a), fixing the root cause.
Testing Steps
the "On This Page:" bar).
expanded). Before this change,
Tabskipped the menu entirely.sticks, the links are reachable, click-to-scroll and active-link highlighting
still work, and scrolling back to the top detaches the menu cleanly.
Equivalent to step 2, you can instead narrow the window to < ~640px to simulate
200% zoom.
Checklist
Links