fix(web): restore always-visible, grabbable scrollbars #511
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/BUNYIP-509-visible-scrollbars"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
bunyip-web/input.cssended with a global::-webkit-scrollbar { display: none }+* { scrollbar-width: none }pair that removed the scrollbar from every scroll container in the app, on every engine. There was no indicator that a pane scrolled, no indicator of position or remaining content, and nothing to grab and drag: scrolling was reduced to wheel or touchpad. The horizontal cases were the worst of it, since anoverflow-x-autotable or code block gave no sign at all that content continued past the right edge. That is an accessibility defect, not a styling preference.Both rules are replaced with explicit, always-visible styling at the same place in the file:
scrollbar-width: auto(neverthin) plus ascrollbar-colorfor Firefox and the standards engines, and a 14px::-webkit-scrollbarwith a painted track, a full-width rounded thumb and a distinct:hoverstate for Chromium and Safari. Declaring the width is also what opts those engines out of the fading OS overlay bar. Every colour comes from the existing theme tokens (--muted,--muted-foreground,--foreground), so light, dark and both high-contrast variants track automatically; the thumb measures 5.3:1 against the light background and 12.5:1 against the dark one.scrollbar-gutter: stableonhtmland on the vertical scroll containers keeps content from shifting when a pane gains or loses its bar. No auto-hide, fade, overlay or hover-to-reveal behaviour is introduced anywhere.The committed Tailwind output
bunyip-web/assets/styles.cssis rebuilt with the pinned tailwindcss 4.3.0 frombun.lock; the only change in it is the replaced scrollbar block.scripts/check-scrollbars.nuis the new guard, wired intocheck.ymlandjust checkalongside the other gates. It fails the build ifscrollbar-width: none,scrollbar-width: thinor adisplay: noneon any::-webkit-scrollbar*pseudo-element reappears in the authored or the built CSS, and also if the visible styling goes missing from either file, so a rebuild that dropped it or a stale asset fails here instead of shipping. CSS comments are stripped before matching, so the comment naming the removed rules does not read as a violation.--self-testexercises eleven cases (authored and minified compliant forms, each hiding shape, a stripped stylesheet, a commented mention in both directions, a missing file).Completeness sweep, every scroll container in
bunyip-web:src/views/layout.rs:538overflow-y-autosrc/views/layout.rs:660APP_MAIN_CLASSmain pane,overflow-y-autosrc/handlers/dashboard.rs:635max-h-[80vh] overflow-y-autosrc/handlers/admin/users.rs:605overflow-x-autosrc/handlers/dashboard.rs:701codeblock,overflow-x-autosrc/handlers/dashboard.rs:718preblock,overflow-x-autosrc/skin/content.rs:706.docs-article pre,overflow-x: autosrc/skin/content.rs:708.docs-article table,overflow-x: autohtml)overflow-hiddenmarkup siteshiddenclips, it never scrolls, so there is no bar to showsrc/views/avatar_picker.rs:39,40,src/handlers/admin/users.rs:667overflow: hidden(sr-only input, avatar circle, shimmer)src/views/layout.rs:800,807,816,822#BUNYIP-509
`bunyip-web/input.css` ended with a global `::-webkit-scrollbar { display: none }` + `* { scrollbar-width: none }` pair that removed the scrollbar from every scroll container in the app, on every engine. There was no indicator that a pane scrolled, no indicator of position or remaining content, and nothing to grab and drag: scrolling was reduced to wheel or touchpad. The horizontal cases were the worst of it, since an `overflow-x-auto` table or code block gave no sign at all that content continued past the right edge. That is an accessibility defect, not a styling preference. Both rules are replaced with explicit, always-visible styling at the same place in the file: `scrollbar-width: auto` (never `thin`) plus a `scrollbar-color` for Firefox and the standards engines, and a 14px `::-webkit-scrollbar` with a painted track, a full-width rounded thumb and a distinct `:hover` state for Chromium and Safari. Declaring the width is also what opts those engines out of the fading OS overlay bar. Every colour comes from the existing theme tokens (`--muted`, `--muted-foreground`, `--foreground`), so light, dark and both high-contrast variants track automatically; the thumb measures 5.3:1 against the light background and 12.5:1 against the dark one. `scrollbar-gutter: stable` on `html` and on the vertical scroll containers keeps content from shifting when a pane gains or loses its bar. No auto-hide, fade, overlay or hover-to-reveal behaviour is introduced anywhere. The committed Tailwind output `bunyip-web/assets/styles.css` is rebuilt with the pinned tailwindcss 4.3.0 from `bun.lock`; the only change in it is the replaced scrollbar block. `scripts/check-scrollbars.nu` is the new guard, wired into `check.yml` and `just check` alongside the other gates. It fails the build if `scrollbar-width: none`, `scrollbar-width: thin` or a `display: none` on any `::-webkit-scrollbar*` pseudo-element reappears in the authored or the built CSS, and also if the visible styling goes missing from either file, so a rebuild that dropped it or a stale asset fails here instead of shipping. CSS comments are stripped before matching, so the comment naming the removed rules does not read as a violation. `--self-test` exercises eleven cases (authored and minified compliant forms, each hiding shape, a stripped stylesheet, a commented mention in both directions, a missing file). Completeness sweep, every scroll container in `bunyip-web`: | Site | Container | Class | | --- | --- | --- | | `src/views/layout.rs:538` | sidebar nav, `overflow-y-auto` | compliant: visible bar + stable gutter | | `src/views/layout.rs:660` | `APP_MAIN_CLASS` main pane, `overflow-y-auto` | compliant: visible bar + stable gutter | | `src/handlers/dashboard.rs:635` | modal body, `max-h-[80vh] overflow-y-auto` | compliant: visible bar + stable gutter | | `src/handlers/admin/users.rs:605` | admin users table wrapper, `overflow-x-auto` | compliant: 14px horizontal bar (gutter N/A, the bar sits on the block edge) | | `src/handlers/dashboard.rs:701` | inline `code` block, `overflow-x-auto` | compliant: 14px horizontal bar | | `src/handlers/dashboard.rs:718` | `pre` block, `overflow-x-auto` | compliant: 14px horizontal bar | | `src/skin/content.rs:706` | `.docs-article pre`, `overflow-x: auto` | compliant: styled by the same global rules | | `src/skin/content.rs:708` | `.docs-article table`, `overflow-x: auto` | compliant: styled by the same global rules | | document scroller (`html`) | public pages and any short viewport | compliant: visible bar + stable gutter | | 16 `overflow-hidden` markup sites | shells, cards, dropdowns, avatars, hero sections | N/A: `hidden` clips, it never scrolls, so there is no bar to show | | `src/views/avatar_picker.rs:39,40`, `src/handlers/admin/users.rs:667` | inline `overflow: hidden` (sr-only input, avatar circle, shimmer) | N/A: same reason | | `src/views/layout.rs:800,807,816,822` | test assertions on those class strings | N/A: test code, not markup | #BUNYIP-509