You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix: keep closed navbar panels out of the tab order - #782
Closed navbar float panels are only faded out (.float-panel-closed → opacity: 0; pointer-events: none), so their links, buttons and inputs keep the default tabIndex of 0 and stay in the sequential focus order. Tabbing past the light/dark switch walks through the controls of four panels that were never opened.
Solution
Add inert to a panel while it carries float-panel-closed. inert removes the whole subtree from focus, hit-testing and the accessibility tree without touching display or visibility, so the open/close transition keeps running and the existing click-outside handlers are unaffected.
src/components/widget/NavMenuPanel.astro, src/components/widget/DisplaySettings.svelte, src/components/LightDarkSwitch.svelte, src/components/Search.svelte — set the attribute in markup so it is correct on the first server-rendered frame.
src/layouts/Layout.astro — syncFloatPanelInert() mirrors the attribute from the closed class, plus a MutationObserver (class-only filter) for the three panels that mount via client:only and for the four places that toggle the class.
The closed class stays the single source of truth, so the open/close state machine is unchanged; there is no fifth panel (grep float-panel src/ matches only these four).
Real Chromium (Playwright 1.61 against astro preview): all four panels closed → inert=true, opacity=0; Tab visits 22 stops on desktop and 18 on mobile with none inside a panel. Opened → inert=false, opacity still animates and the controls are focusable; click-outside / mouseleave restore inert.
pnpm check reports 2 errors that are identical on the base commit (Navbar.astro, archive.astro), and Biome reports 5 pre-existing formatter diagnostics on these files; the added lines are unchanged from baseline formatting.
Thanks for this fix — the inert approach is solid and keeps the open/close transitions untouched.
For the maintainers' consideration, there is a one-line CSS alternative that also fully fixes #777: adding visibility: hidden to .float-panel-closed removes the whole subtree from the tab order and the accessibility tree, since visibility: hidden is inherited and disables focusability.
Panels using Tailwind's default transition class (e.g. #light-dark-panel) do not transition visibility by default, so the close animation would snap unless visibility is added to transition-property (panels using transition-all are unaffected).
inert additionally blocks assistive-tech traversal and hit testing explicitly, which some may prefer semantically.
Verified against main (6d39b0d) with keyboard walks at 1280×720 and 390×844: with the CSS change, invisible focus stops drop from 9 (desktop) / 7 (mobile) to 0, and all four panels still open, close and re-close correctly. Either approach works; sharing the measurement in case it helps the decision.
This branch has not been deployed
No deployments
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
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.
Closes #777.
Problem
Closed navbar float panels are only faded out (
.float-panel-closed→opacity: 0; pointer-events: none), so their links, buttons and inputs keep the defaulttabIndexof 0 and stay in the sequential focus order. Tabbing past the light/dark switch walks through the controls of four panels that were never opened.Solution
Add
inertto a panel while it carriesfloat-panel-closed.inertremoves the whole subtree from focus, hit-testing and the accessibility tree without touchingdisplayorvisibility, so the open/close transition keeps running and the existing click-outside handlers are unaffected.src/components/widget/NavMenuPanel.astro,src/components/widget/DisplaySettings.svelte,src/components/LightDarkSwitch.svelte,src/components/Search.svelte— set the attribute in markup so it is correct on the first server-rendered frame.src/layouts/Layout.astro—syncFloatPanelInert()mirrors the attribute from the closed class, plus aMutationObserver(class-only filter) for the three panels that mount viaclient:onlyand for the four places that toggle the class.The closed class stays the single source of truth, so the open/close state machine is unchanged; there is no fifth panel (
grep float-panel src/matches only these four).Validation
pnpm buildsucceeds: 8 pages built, Pagefind indexed 6 pages.dist/index.html→<div id="nav-menu-panel" class="float-panel float-panel-closed …" inert>.astro preview): all four panels closed →inert=true, opacity=0; Tab visits 22 stops on desktop and 18 on mobile with none inside a panel. Opened →inert=false, opacity still animates and the controls are focusable; click-outside / mouseleave restoreinert.pnpm checkreports 2 errors that are identical on the base commit (Navbar.astro,archive.astro), and Biome reports 5 pre-existing formatter diagnostics on these files; the added lines are unchanged from baseline formatting.