Components
Augments native scroll functionality for custom, cross-browser styling.
Playground
className. Scrolling stays native; only the scrollbar is custom, styled with the border token so it sits on any surface. The separately exported ScrollBar is only needed for horizontal scrolling.import { ScrollArea } from "@workspace/ui/components/scroll-area"
<ScrollArea className="h-72 w-48 rounded-md border">
<div className="p-4">
<h4 className="mb-4 text-sm leading-none font-medium">Tags</h4>
{tags.map((tag) => (
<React.Fragment key={tag}>
<div className="text-sm">{tag}</div>
<Separator className="my-2" />
</React.Fragment>
))}
</div>
</ScrollArea>flex w-max plus whitespace-nowrap on the area — and add <ScrollBar orientation="horizontal" /> as a child. The built-in vertical scrollbar stays out of the way since nothing overflows vertically, and because browsers only wheel-scroll the axis that overflows, ScrollArea translates a plain mouse wheel into horizontal scrolling here — trackpads swipe natively either way.import { ScrollArea, ScrollBar } from "@workspace/ui/components/scroll-area"
<ScrollArea className="w-96 rounded-md border whitespace-nowrap">
<div className="flex w-max gap-4 p-4">
{artworks.map((artwork) => (
<figure key={artwork} className="shrink-0">
<div className="h-40 w-28 rounded-md bg-muted" />
<figcaption className="pt-2 text-xs text-muted-foreground">
{artwork}
</figcaption>
</figure>
))}
</div>
<ScrollBar orientation="horizontal" />
</ScrollArea><ScrollArea className="h-72 w-96 rounded-md border">
<div className="w-max p-4">{/* wide and tall content */}</div>
<ScrollBar orientation="horizontal" />
</ScrollArea>type prop controls when the scrollbar shows: hover (default) reveals it while the pointer is over the area, scroll while scrolling, auto whenever content overflows, and always keeps it permanently visible. scrollHideDelay tunes how long hover and scroll wait before fading it out.<ScrollArea className="h-48 w-96 rounded-md border" type="always">
{/* long content */}
</ScrollArea>// keyboard users scroll the focused viewport natively —
// Tab into the area, then use arrows, PageUp/PageDown, Home/End
<ScrollArea className="h-72 rounded-md border" type="always">
{/* content */}
</ScrollArea>dir prop or an ancestor — moves the vertical scrollbar to the correct side.| Part | Prop | Default |
|---|---|---|
| ScrollArea | type?: "hover" | "always" | "scroll" | "auto" | "hover" |
| ScrollArea | scrollHideDelay?: number | 600 |
| ScrollArea | dir?: "ltr" | "rtl" | inherited |
| ScrollBar | orientation?: "vertical" | "horizontal" | "vertical" |
| ScrollBar | forceMount?: true | — |
Tokens used
3 design tokens consumed by the Scroll Area component.
--border
Border
--ring
Ring
--spacing
Spacing unit (4px)