Scrollbars
One axis for every scroll container: the browser's bar, a macOS overlay, the Windows Fluent bar or none at all, plus what the page does under a dialog.
Styles#
Each box below carries its own style. Scroll them, hover them, grab a thumb. The bars are drawn from the foreground role, so they follow every theme and concept with no extra work.
| INV-1042 | Northwind Studio | Due Nov 18 | €1,240.00 |
| INV-1043 | Halcyon Labs | Due Nov 19 | €860.00 |
| INV-1044 | Fernhill & Co | Due Nov 21 | €3,120.00 |
| INV-1045 | Atlas Freight | Due Nov 22 | €415.50 |
| INV-1046 | Mirador Hotels | Due Nov 24 | €2,080.00 |
| INV-1047 | Quarry Coffee | Due Nov 25 | €96.40 |
| INV-1048 | Lumen Health | Due Nov 27 | €5,400.00 |
| INV-1049 | Pine Ridge Farms | Due Nov 28 | €728.00 |
| INV-1050 | Orbit Mobility | Due Dec 01 | €1,915.00 |
| INV-1051 | Salt & Ember | Due Dec 02 | €342.00 |
| INV-1042 | Northwind Studio | Due Nov 18 | €1,240.00 |
| INV-1043 | Halcyon Labs | Due Nov 19 | €860.00 |
| INV-1044 | Fernhill & Co | Due Nov 21 | €3,120.00 |
| INV-1045 | Atlas Freight | Due Nov 22 | €415.50 |
| INV-1046 | Mirador Hotels | Due Nov 24 | €2,080.00 |
| INV-1047 | Quarry Coffee | Due Nov 25 | €96.40 |
| INV-1048 | Lumen Health | Due Nov 27 | €5,400.00 |
| INV-1049 | Pine Ridge Farms | Due Nov 28 | €728.00 |
| INV-1050 | Orbit Mobility | Due Dec 01 | €1,915.00 |
| INV-1051 | Salt & Ember | Due Dec 02 | €342.00 |
| INV-1042 | Northwind Studio | Due Nov 18 | €1,240.00 |
| INV-1043 | Halcyon Labs | Due Nov 19 | €860.00 |
| INV-1044 | Fernhill & Co | Due Nov 21 | €3,120.00 |
| INV-1045 | Atlas Freight | Due Nov 22 | €415.50 |
| INV-1046 | Mirador Hotels | Due Nov 24 | €2,080.00 |
| INV-1047 | Quarry Coffee | Due Nov 25 | €96.40 |
| INV-1048 | Lumen Health | Due Nov 27 | €5,400.00 |
| INV-1049 | Pine Ridge Farms | Due Nov 28 | €728.00 |
| INV-1050 | Orbit Mobility | Due Dec 01 | €1,915.00 |
| INV-1051 | Salt & Ember | Due Dec 02 | €342.00 |
| INV-1042 | Northwind Studio | Due Nov 18 | €1,240.00 |
| INV-1043 | Halcyon Labs | Due Nov 19 | €860.00 |
| INV-1044 | Fernhill & Co | Due Nov 21 | €3,120.00 |
| INV-1045 | Atlas Freight | Due Nov 22 | €415.50 |
| INV-1046 | Mirador Hotels | Due Nov 24 | €2,080.00 |
| INV-1047 | Quarry Coffee | Due Nov 25 | €96.40 |
| INV-1048 | Lumen Health | Due Nov 27 | €5,400.00 |
| INV-1049 | Pine Ridge Farms | Due Nov 28 | €728.00 |
| INV-1050 | Orbit Mobility | Due Dec 01 | €1,915.00 |
| INV-1051 | Salt & Ember | Due Dec 02 | €342.00 |
native
mac
windows
hidden
Page-wide#
Picked here, the style lands on <html> and reaches every scroller on the page, menus and dialogs included. Then open the dialog to feel the lock.
Under a dialog#
lock is the default: the page freezes under any modal (Dialog, Sheet, Alert Dialog, a modal menu). With a styled bar the gutter stays reserved, so when the bar goes nothing slides sideways, not even a fixed header. free lets the page keep scrolling under the dialog while focus stays trapped inside it.
lock
free
Setup#
The styles ship in app/scrollbars.css, imported from globals.css. For a fixed style, set the attributes on <html> and you are done. To let people pick, mount ScrollbarProvider: it persists the choice, shows the macOS bar while scrolling and runs the free lock.
<html data-scrollbar="mac" data-scroll-lock="lock">
<body>
<ScrollbarProvider>{children}</ScrollbarProvider>
</body>
</html>The attribute also scopes: put data-scrollbar on any wrapper and only that subtree changes. A component that hides its own bar (TabStrip, Lightbox, InkTray) keeps it hidden under every style. Retune the ink per theme with the tokens.
:root {
--scrollbar-thumb: color-mix(in oklab, var(--foreground) 32%, transparent);
--scrollbar-thumb-hover: color-mix(in oklab, var(--foreground) 48%, transparent);
--scrollbar-thumb-active: color-mix(in oklab, var(--foreground) 60%, transparent);
--scrollbar-track: color-mix(in oklab, var(--foreground) 5%, transparent);
--scrollbar-arrow: color-mix(in oklab, var(--foreground) 55%, transparent);
}Chrome, Edge and Safari draw the full shapes. Firefox has no way to style a scrollbar beyond width and colour, so it gets a thin bar in the same ink, and the macOS one still hides at rest.