- Shipped
- September 5, 2026 at 8:43 PM UTC
- Author
- Kamo
- Commit
- 8a3c8aa
Painting the bar over the last 32px is fine over a background — the launchpad's wallpaper does not mind — and wrong everywhere else. In a chat log it lands on the message bubbles; in the nav rail it lands on the icons. The content now moves, and the browser is what moves it. The native scrollbar is not removed any more: it is widened to 32px and coloured fully transparent, so the browser reserves the gutter exactly as it always has, and our bar is drawn over that gutter — which works out because the gutter lives inside the padding box, and the padding box is what the overlay already measures. Reserving this way rather than with `padding-inline-end` is not a detail: - No `!important` needed to beat an `sx` prop, and no guessing what padding a panel already carried. The one previous user of the padding rule, the page scroller in AuthedChrome, gives it up and gets the same result. - It applies to every scroller at once, instead of one opt-in at a time. - The space is taken ONLY while the element is scrolling. A panel whose content fits keeps its full width — which no padding rule could manage, and which is the difference between reserving a gutter and losing 32px of every marked element in the app forever. `data-kamo-scrollbar="off"` still suppresses the bar AND the gutter, so a tab strip whose arrows and faded edge are the affordance gets its full height back. Checked in a browser, not in jsdom, which does no layout and cannot see a scrollbar at all: a chat log (bubbles clear of the bar), an 80px nav rail (icons pushed left, not covered), a panel that is not scrolling (its background still reaches the right edge, so nothing was reserved) and a 250px popover. Firefox is the one imperfect case — it reserves its own narrower gutter, so the bar overhangs it by a few pixels there.