Skip to content

[WCAG 2.4.11] Add scroll-padding to prevent sticky overlays from obscuring focused elements#3532

Open
rosanusi wants to merge 2 commits into
mainfrom
wcag/2.4.11-scroll-accommodation
Open

[WCAG 2.4.11] Add scroll-padding to prevent sticky overlays from obscuring focused elements#3532
rosanusi wants to merge 2 commits into
mainfrom
wcag/2.4.11-scroll-accommodation

Conversation

@rosanusi

Copy link
Copy Markdown

Description

Fixes WCAG 2.2 SC 2.4.11 (Focus Not Obscured — Minimum) across all authenticated routes. ui-main had seven persistent sticky/fixed overlays and zero scroll accommodation — keyboard-focused elements below the fold would auto-scroll flush with the viewport top, placing them entirely behind the top-nav or other overlays.

Root cause: scroll-padding-top and scroll-padding-bottom were never applied to any scroll container in the codebase (confirmed via negative grep). The fix is structural: add scroll accommodation to the two scroll contexts where obscuring occurs.

Changes:

  • src/app.css — Adds --banner-height: 0px and --bottom-nav-height: 4rem (reset to 0px at md breakpoint) to :root so both values are always defined and mobile/desktop behave correctly without JavaScript.

  • src/lib/holocene/main-content-container.svelte — Applies scroll-padding-top: calc(var(--top-nav-height, 3rem) + var(--banner-height, 0px)) and scroll-padding-bottom: var(--bottom-nav-height, 0px) on #content-wrapper. Covers: top-nav (always present), conditional banner stacking, and mobile bottom-nav.

  • src/lib/holocene/banner/banner.svelte — Measures actual banner height via bind:clientHeight and publishes it to --banner-height on :root reactively. Resets to 0px when banner is dismissed or not shown, keeping the page-level scroll-padding-top accurate.

  • src/lib/holocene/table/paginated-table/index.svelte — Applies scroll-padding-top: var(--table-header-h, 2.25rem) and scroll-padding-bottom: {footerHeight}px on the table scroll container (nested scroll context). footerHeight is measured live via bind:clientHeight on the sticky footer div. Covers: Holocene Table sticky <thead> and paginated-table sticky footer.

Overlays addressed:

Overlay Location Fix
top-nav src/lib/components/top-nav.svelte:26 scroll-padding-top via --top-nav-height
Table sticky <thead> src/lib/holocene/table/table.svelte:74 scroll-padding-top on paginated-table container
paginated-table footer src/lib/holocene/table/paginated-table/index.svelte:65 scroll-padding-bottom tracked live
Banner conditional sticky src/lib/holocene/banner/banner.svelte:19 --banner-height measured and stacked into calc()
bottom-nav (mobile) src/lib/components/bottom-nav.svelte:138 scroll-padding-bottom via --bottom-nav-height
Drawer src/lib/holocene/drawer.svelte:70 No fix needed — contains own focus trap
Toaster src/lib/holocene/toaster.svelte:26 No fix needed — transient, auto-dismisses

Screenshots

No visual change at rest. The fix affects scroll position when focusing elements below the viewport fold via keyboard navigation.

Design

N/A — structural CSS fix, no visual design change.

Testing

  • Keyboard tab-through on a long workflow list (50+ rows) — confirm focused row is visible above top-nav
  • With a banner rendered — confirm focused element clears top-nav + banner combined height
  • Mobile viewport — confirm focused element clears bottom-nav
  • Holocene Table (any paginated list) — confirm focused cells in table body are not hidden behind sticky <thead>
  • Paginated table footer — confirm focused elements in last rows are not hidden behind sticky footer
  • Dismiss banner — confirm --banner-height resets to 0px and scroll-padding-top shrinks accordingly
  • Anchor links and programmatic scrollIntoView — confirm no regression

Checklist

  • I have performed a self-review of my own code
  • I have added tests for my changes (N/A — CSS-only; deterministic from spec)
  • I have read the contributor guidelines

Docs

No documentation changes required.

A11y-Audit-Ref: 2.4.11-scroll-accommodation-missing

…elements

Ensures keyboard-focused items are not hidden behind the top nav, sticky
banners, bottom nav, or sticky table headers/footers per SC 2.4.11.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
holocene Ready Ready Preview, Comment Jun 11, 2026 4:24pm

Request Review

@temporal-cicd

temporal-cicd Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor
Warnings
⚠️

📊 Strict Mode: 1 error in 1 file (0.1% of 902 total)

src/lib/holocene/banner/banner.svelte (1)
  • L64:13: Type 'null' is not assignable to type '"search" | "link" | "success" | "error" | "action" | "activity" | "add-square" | "add" | "apple" | "archives" | "arrow-down" | "arrow-left" | "arrow-up" | "arrow-right" | "ascending" | ... 141 more ... | "xmark-square"'.

Generated by 🚫 dangerJS against a67445c

…line-before errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@rosanusi rosanusi marked this pull request as ready for review June 11, 2026 16:35
@rosanusi rosanusi requested a review from a team as a code owner June 11, 2026 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant