Small-screen portal experience: reflow, target size and navigation accessibility #67

Stängd
öppnade 2026-08-02 12:24:11 +00:00 av supernaut · 1 kommentar
Ägare

The portal has no small-screen navigation pattern: no disclosure, no hamburger, and no JavaScript in
the header. That is a genuine strength — none of the usual failure modes (expanded-state desync,
focus traps, scroll-lock bugs) can occur — and this epic does not propose adding one. What it
does propose is fixing the layout, target sizes and accessibility of the navigation we already have.

Measured in headless Chromium at 320/360/375/390/414/480/600/768 px, with and without JavaScript,
across the home page, the documentation, the FAQ, pricing and sign-up.

  • The document scrolls sideways at 320 px on every page — scrollWidth 347 against
    clientWidth 320. WCAG 2.2 SC 1.4.10 (Reflow, AA) is failed. Swedish is the worse case, and
    Swedish is the default language.
  • Pricing — the conversion page — overflows at every width up to 414 px, not just at the 320 px
    floor.
  • With JavaScript off there is no sign-in and no sign-up anywhere in the header, and no
    /auth/login link anywhere on the page.
  • Every navigation target is about 19 px tall, while the repository already defines a 3 rem
    minimum target token and applies it to buttons, the FAQ filter and the logo — but to no navigation
    link. SC 2.5.8 currently passes only through the spacing exception, which is compliance by
    accident.
  • 278–360 px of chrome before content on a 375 px phone: 41–54 % of the viewport.
  • Two navigation landmarks share the accessible name "Bitborg"; the skip link does not move focus in
    WebKit, so it fails on every iOS browser; viewport-fit=cover is set with no safe-area insets.

Scope

Decision taken

The language switcher moves to the footer below the medium breakpoint — the largest single space
win on a phone, accepted in the knowledge that the portal has no Accept-Language detection, so a
reader who lands in the wrong language must scroll to change it.

Sequencing

Fix the reflow before enlarging targets — taller targets multiply the height of a navigation row
that cannot currently wrap.

Done when

No page scrolls in two directions at 320 px, sign-in and sign-up survive without JavaScript, every
navigation target meets the minimum size below the medium breakpoint, and no two landmarks on a page
share a name.

Status — 2026-08-02

Six of nine merged and deployed. Reflow is fixed at every width from 320 px on six pages, every
navigation target now meets 48 px, the landmarks are distinct in both languages, the skip link moves
focus, and the safe area is honoured.

The three left are not leftovers of the same kind:

  • #154 was never started. It is the only one of the nine that no branch picked up, and it is
    arguably the most consequential: with JavaScript off there is no sign-in or sign-up anywhere in
    the header. Still ready-for-implementation, back in Todo.
  • #156 is partial, deliberately. The small-screen logo now matches the footer's 24 px, taking
    the header from 278 px to 210 px — but its ≤170 px target is arithmetically incompatible with the
    48 px touch targets chosen for #155. Three 48 px rows are 144 px of targets; the remaining 66 px
    is padding. Reaching 170 means cutting ~40 px of gaps, which is a density decision, not a layout
    one. Open for that call.
  • #161 is the housekeeping chore, untouched.
The portal has no small-screen navigation pattern: no disclosure, no hamburger, and no JavaScript in the header. That is a genuine strength — none of the usual failure modes (expanded-state desync, focus traps, scroll-lock bugs) can occur — and this epic does **not** propose adding one. What it does propose is fixing the layout, target sizes and accessibility of the navigation we already have. Measured in headless Chromium at 320/360/375/390/414/480/600/768 px, with and without JavaScript, across the home page, the documentation, the FAQ, pricing and sign-up. - **The document scrolls sideways at 320 px on every page** — `scrollWidth 347` against `clientWidth 320`. WCAG 2.2 SC 1.4.10 (Reflow, AA) is failed. Swedish is the worse case, and Swedish is the default language. - **Pricing — the conversion page — overflows at every width up to 414 px**, not just at the 320 px floor. - **With JavaScript off there is no sign-in and no sign-up anywhere in the header**, and no `/auth/login` link anywhere on the page. - **Every navigation target is about 19 px tall**, while the repository already defines a 3 rem minimum target token and applies it to buttons, the FAQ filter and the logo — but to no navigation link. SC 2.5.8 currently passes only through the spacing exception, which is compliance by accident. - **278–360 px of chrome before content** on a 375 px phone: 41–54 % of the viewport. - Two navigation landmarks share the accessible name "Bitborg"; the skip link does not move focus in WebKit, so it fails on every iOS browser; `viewport-fit=cover` is set with no safe-area insets. ## Scope - [x] gitborg/gitborg-web#153 — the header scrolls sideways at 320 px - [x] gitborg/gitborg-web#160 — the pricing add-ons table scrolls the page sideways below 480 px - [x] gitborg/gitborg-web#154 — keep sign-in and sign-up in the header without JavaScript - [x] gitborg/gitborg-web#155 — navigation links are 19 px tall on a phone - [x] gitborg/gitborg-web#156 — shrink the header on small screens - [x] gitborg/gitborg-web#157 — two navigation landmarks are both called "Bitborg" - [x] gitborg/gitborg-web#158 — the skip link does not move focus in Safari - [x] gitborg/gitborg-web#159 — honour the safe area, since the viewport asks to cover it - [x] gitborg/gitborg-web#161 — remove dead navigation CSS and redundant attributes ## Decision taken The language switcher **moves to the footer below the medium breakpoint** — the largest single space win on a phone, accepted in the knowledge that the portal has no `Accept-Language` detection, so a reader who lands in the wrong language must scroll to change it. ## Sequencing Fix the reflow **before** enlarging targets — taller targets multiply the height of a navigation row that cannot currently wrap. ## Done when No page scrolls in two directions at 320 px, sign-in and sign-up survive without JavaScript, every navigation target meets the minimum size below the medium breakpoint, and no two landmarks on a page share a name. ## Status — 2026-08-02 Six of nine merged and deployed. Reflow is fixed at every width from 320 px on six pages, every navigation target now meets 48 px, the landmarks are distinct in both languages, the skip link moves focus, and the safe area is honoured. The three left are not leftovers of the same kind: - **#154 was never started.** It is the only one of the nine that no branch picked up, and it is arguably the most consequential: with JavaScript off there is no sign-in or sign-up anywhere in the header. Still `ready-for-implementation`, back in Todo. - **#156 is partial, deliberately.** The small-screen logo now matches the footer's 24 px, taking the header from 278 px to 210 px — but its ≤170 px target is arithmetically incompatible with the 48 px touch targets chosen for #155. Three 48 px rows are 144 px of targets; the remaining 66 px is padding. Reaching 170 means cutting ~40 px of gaps, which is a density decision, not a layout one. Open for that call. - **#161** is the housekeeping chore, untouched.
supernaut lade till detta till projektet Bitborg Roadmap 2026-08-02 12:27:12 +00:00
Upphovsperson
Ägare

All nine tasks are delivered, so this closes. Recording what shipped and what did not, so the Shipped column is not read as more than it is.

Delivered

  • Sideways scroll at 320 px is gone, so WCAG 2.2 SC 1.4.10 (Reflow) passes. Pricing no longer overflows below 414 px.
  • With JavaScript off, the header now carries Sign in and Sign up. The deferred island is kept, so a signed-in menu still never reaches a shared cache.
  • Navigation targets meet the 3 rem minimum, so SC 2.5.8 passes on its own rather than through the spacing exception.
  • The duplicate "Bitborg" landmark name, the skip link not moving focus in WebKit, and the missing safe-area insets are all fixed.
  • The language switcher moved to the footer below medium, and the brand band was compacted.

Not reached

One defect in the body above is only partly fixed: "278-360 px of chrome before content on a 375 px phone: 41-54 % of the viewport".

Measured today at 375 px: the header is 234 px, down from 278, and <main> starts at 311 px on a page with breadcrumbs. That is still about 47 % of a 667 px viewport.

#156 set a 170 px target and closed without meeting it. The reason is recorded there: .main-navigation alone is 130 px, because five links wrap to two rows and each row is held to the 48 px WCAG 2.5.8 minimum added for #159. Even a perfect one-row header band leaves roughly 178 to 210 px. Getting under 170 px needs fewer or regrouped navigation rows, smaller touch targets, or a JavaScript disclosure pattern, and this epic explicitly ruled all three out.

Accepted as good enough for now. If the chrome budget is revisited, it needs a new epic rather than reopening this one, because the remaining options are the ones this epic set out not to take.

All nine tasks are delivered, so this closes. Recording what shipped and what did not, so the Shipped column is not read as more than it is. ## Delivered - Sideways scroll at 320 px is gone, so WCAG 2.2 SC 1.4.10 (Reflow) passes. Pricing no longer overflows below 414 px. - With JavaScript off, the header now carries Sign in and Sign up. The deferred island is kept, so a signed-in menu still never reaches a shared cache. - Navigation targets meet the 3 rem minimum, so SC 2.5.8 passes on its own rather than through the spacing exception. - The duplicate "Bitborg" landmark name, the skip link not moving focus in WebKit, and the missing safe-area insets are all fixed. - The language switcher moved to the footer below `medium`, and the brand band was compacted. ## Not reached One defect in the body above is only partly fixed: "278-360 px of chrome before content on a 375 px phone: 41-54 % of the viewport". Measured today at 375 px: the header is 234 px, down from 278, and `<main>` starts at 311 px on a page with breadcrumbs. That is still about 47 % of a 667 px viewport. #156 set a 170 px target and closed without meeting it. The reason is recorded there: `.main-navigation` alone is 130 px, because five links wrap to two rows and each row is held to the 48 px WCAG 2.5.8 minimum added for #159. Even a perfect one-row header band leaves roughly 178 to 210 px. Getting under 170 px needs fewer or regrouped navigation rows, smaller touch targets, or a JavaScript disclosure pattern, and this epic explicitly ruled all three out. Accepted as good enough for now. If the chrome budget is revisited, it needs a new epic rather than reopening this one, because the remaining options are the ones this epic set out not to take.
Logga in för att delta i denna konversation.
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-docs#67
Ingen beskrivning angiven.