Scroll Area
Scroll container with thin scrollbars that stay inside its frame.
Installation
pnpm dlx shadcn@latest add @paneui/scroll-areaUsage
Composition
Examples
Track placement
Each track sits inside the frame, scrollbarInset (4px) from its edges, so it never runs past a rounded corner. Where a corner's radius would still clip the thumb's cap, that end moves in until the cap clears the curve by 1px (7px on an 18px corner). Where both bars show, each stops 8px short of the other. The thumb always covers the whole scroll range.
Visibility
The 6px bars overlay the content and take no width. They show while the pointer is over the area or it is scrolling, and fade out 300ms after. The hit area is 4px wider on each side than the track.
Height
Give the root a fixed height (h-72), or leave it auto and put max-h-* on viewportClassName. A max-h-* on the root alone never scrolls.
Accessibility
The viewport joins the tab order only while it can scroll, so keyboard users can scroll it with the arrow keys; it shows the focus ring inset.
Overlays
The root publishes --scroll-area-inset, --scroll-area-radius-top and --scroll-area-radius-bottom, so content inside can follow the frame's edge. Scroll Progress uses them for its sticky bar.
API Reference
Built on the Scroll Area primitive. Only the props this library adds or changes are listed; everything else passes through.
ScrollArea
Root and viewport in one, with its own scrollbars. Also accepts every prop of ScrollArea.Root.
- orientation= "vertical"
- "vertical" | "horizontal" | "both"
- Which scrollbars to show. The other axis is clipped.
- scrollbarInset= 4
- number
- Gap in px between each track and the frame edges.
- scrollbarMargin
- { top?: number; bottom?: number; start?: number; end?: number }
- Extra px on one side, added to the inset, such as a sticky header's height on
top. - fade= false
- boolean
- Fades content over 24px at an edge while there is more to scroll there.
- viewportRef
- Ref<HTMLDivElement>
- The element that scrolls, for scroll listeners, virtualizers and
scrollTo. - viewportClassName
- string
- Classes for the element that scrolls.
- viewportProps
- ComponentProps<"div">
- Props for the element that scrolls, such as
role,aria-*,onScrollorstyle.
| Prop | Type | Default | Description |
|---|---|---|---|
| orientation | "vertical" | "horizontal" | "both" | "vertical" | Which scrollbars to show. The other axis is clipped. |
| scrollbarInset | number | 4 | Gap in px between each track and the frame edges. |
| scrollbarMargin | { top?: number; bottom?: number; start?: number; end?: number } | — | Extra px on one side, added to the inset, such as a sticky header's height on top. |
| fade | boolean | false | Fades content over 24px at an edge while there is more to scroll there. |
| viewportRef | Ref<HTMLDivElement> | — | The element that scrolls, for scroll listeners, virtualizers and scrollTo. |
| viewportClassName | string | — | Classes for the element that scrolls. |
| viewportProps | ComponentProps<"div"> | — | Props for the element that scrolls, such as role, aria-*, onScroll or style. |
- data-scrolling
- Present while the area is scrolling.
- data-has-overflow-x / -y
- Present while the content overflows on that axis.
- data-overflow-y-start / -end
- Present while there is more to scroll towards that edge (also
-x-).
| Data attribute | Description |
|---|---|
| data-scrolling | Present while the area is scrolling. |
| data-has-overflow-x / -y | Present while the content overflows on that axis. |
| data-overflow-y-start / -end | Present while there is more to scroll towards that edge (also -x-). |
ScrollBar
One overlay scrollbar, placed from the root's inset variables. ScrollArea renders its own; use this only when composing the primitive parts yourself. Also accepts every prop of ScrollArea.Scrollbar.
- orientation= "vertical"
- "vertical" | "horizontal"
- Axis the bar scrolls.
| Prop | Type | Default | Description |
|---|---|---|---|
| orientation | "vertical" | "horizontal" | "vertical" | Axis the bar scrolls. |
- data-hovering
- Present while the pointer is over the area.
| Data attribute | Description |
|---|---|
| data-hovering | Present while the pointer is over the area. |