Problem
The Lighthouse target-size audit fails on the current-section link in the sidebar pages dropdown:
div#pages-dropdown > button.w-full > div > a.pages-dropdown_active
Target: 96.9 px × 21.5 px; required safe target: at least 24 px × 24 px
The markup also places an <a> inside a <button>, which is invalid nested interactive content. The dropdown is opened through CSS :focus-within, has no aria-expanded/aria-controls state, and requires a mousedown focus workaround.
Relevant code
src/Elastic.Documentation.Site/Navigation/_TocTree.cshtml
src/Elastic.Documentation.Site/Assets/pages-nav.ts
src/Elastic.Documentation.Site/synthetics/journeys/navigation-test.journey.ts
Proposed implementation
- Replace the nested
button > a structure with sibling controls in one row:
- a full-height current-section link with a minimum 24 px target;
- a dedicated disclosure button for the chevron.
- Give the button
type="button", aria-expanded, and aria-controls pointing to a stable menu ID.
- Remove
tabindex="0" from the non-interactive wrapper.
- Manage open/close explicitly in
pages-nav.ts, including Space/Enter through native button behavior, Escape to close and restore focus, outside click/focus, and state synchronization after htmx navigation.
- Remove
preventFocusLossOnLinkClick; it should no longer be needed.
Acceptance criteria
- No interactive element contains another interactive element.
- Both the current-section link and disclosure button have a target of at least 24 px × 24 px.
aria-expanded accurately reflects menu visibility and aria-controls references the menu.
- Keyboard users can open, close, navigate, and Escape from the menu.
- Existing link preloading and htmx navigation continue to work.
- Jest tests cover open/close, Escape, and ARIA state.
- The synthetic navigation journey uses the disclosure button by role and still reaches
/docs/reference.
- Lighthouse no longer reports the pages-dropdown target-size failure.
Problem
The Lighthouse
target-sizeaudit fails on the current-section link in the sidebar pages dropdown:The markup also places an
<a>inside a<button>, which is invalid nested interactive content. The dropdown is opened through CSS:focus-within, has noaria-expanded/aria-controlsstate, and requires a mousedown focus workaround.Relevant code
src/Elastic.Documentation.Site/Navigation/_TocTree.cshtmlsrc/Elastic.Documentation.Site/Assets/pages-nav.tssrc/Elastic.Documentation.Site/synthetics/journeys/navigation-test.journey.tsProposed implementation
button > astructure with sibling controls in one row:type="button",aria-expanded, andaria-controlspointing to a stable menu ID.tabindex="0"from the non-interactive wrapper.pages-nav.ts, including Space/Enter through native button behavior, Escape to close and restore focus, outside click/focus, and state synchronization after htmx navigation.preventFocusLossOnLinkClick; it should no longer be needed.Acceptance criteria
aria-expandedaccurately reflects menu visibility andaria-controlsreferences the menu./docs/reference.