Scrollbars
A scrollbar that stays out of the way but never disappears, over shadcn's scroll-fade as the baseline edge treatment — restyled to the shape system, with native scroll physics on touch.
Installation
Installs the ScrollArea component with the shape-system scrollbar and the scroll-fade edge treatment.
The problem
macOS hides the scrollbar until you start scrolling, so a clipped list gives no sign it has more below. And the moment it does appear, it's the grey OS default sitting on top of your design. You either get no affordance or the wrong one.
The scrollbar
The thumb rests narrow and low-contrast, then widens and darkens on hover so it stays quiet until you reach for it. Press R to see the radius follow the shape system. On touch-primary devices the whole thing steps aside for native overflow scrolling, where platform physics beat any custom scrollbar.
BoringUI uses the Base UI implementation with the same public API as the upstream variants. Scrollbar machinery adapted from Lina.
The fade
The baseline edge treatment is shadcn's scroll-fade, vendored as a CSS utility in globals.css. A mask dissolves the content toward the edges that have more to scroll, and a scroll-driven animation keeps the true start and end crisp. Drop scroll-fade (or scroll-fade-x) on the viewport and it rides under the scrollbar — no JavaScript.
Examples
Horizontal
A row wider than its container, faded with the x variant.
Double overflow
A table taller and wider than its box. orientation="both" adds both scrollbars and the corner.
API reference
ScrollArea
| Prop | Type | Default | Description |
|---|---|---|---|
| orientation | "vertical" | "horizontal" | "both" | "vertical" | Which axes get scrollbars. |
| viewportClassName | string | — | Classes for the inner scrolling viewport — where the scroll-fade utility goes. |
| className | string | — | Classes for the outer container — set the height/width constraint here. |