Scroll area
Scrolls its content in a fixed-size box, with slim scrollbars.
Installation
The CLI installs the Radix or Base UI file to match your project.
If your project doesn't have Wisty UI's theme yet, add it once with npx shadcn@latest add @wisty/cosmos. Until then, components keep shadcn's default look. Installation has the details.
When to use
Use it
- A list, panel or table must fit a fixed height or width, and the rest scrolls inside it.
- A row of tiles or cards is wider than the space it has.
- A scrolling box whose scrollbar should match the theme on every system.
Don't use it
- The whole page scrolls. Let the browser scroll it.
- A table only needs to scroll sideways. Table does that on its own.
- A long table, or one with sorting or selection. Use Data table: given a height it scrolls under a header that stays put, and
virtualizedraws only the rows on screen. - Options in a menu, select or combobox. Dropdown menu, Select and Combobox cap their own height and scroll.
Usage
Give ScrollArea a fixed size and put the content inside. It scrolls up and down; for sideways scrolling add <ScrollBar orientation="horizontal" /> as the last child, as the Horizontal example shows.
import { ScrollArea } from "@/components/ui/scroll-area"<ScrollArea className="h-72 rounded-(--radius-2) border">
<div className="p-4">{/* content taller than the area */}</div>
</ScrollArea>In Radix projects, the scrollbar shows while the pointer is over the area and hides after the pointer leaves; pass type="always" to keep it shown. In Base UI projects, it shows whenever the content overflows. In Radix projects the content also sits in a display: table box, where truncate doesn't cut text and percentage widths don't follow the area.
Examples
Horizontal
A row of opportunity tiles that scrolls sideways, with `<ScrollBar orientation="horizontal" />` as the last child.
Both directions
A plain `table` of cases wider and taller than its box, with the default vertical bar and a horizontal `ScrollBar`.
API reference
| Part | Built on |
|---|---|
ScrollArea | Radix ScrollArea.Root (opens in a new tab) |
ScrollBar | Radix ScrollArea.Scrollbar (opens in a new tab) |
ScrollBar
| Prop | Type | Default |
|---|---|---|
orientation | "horizontal" | "vertical" | "vertical" |
SLDS mapping
SLDS 2 has no scroll area and doesn't style scrollbars. ScrollArea is the box of slds-scrollable, and ScrollBar is slds-scrollable_y or slds-scrollable_x, which keep the browser's own scrollbar. The bar and its pill thumb are drawn from SLDS's neutral and surface tokens, and the area clips them to its corners.
Known gaps:
- The corner where the two bars meet stays clear. Native scrollbars fill it.
- Select, Dropdown menu and Table scroll with the browser's own scrollbar. Only Scroll area draws one, so with classic scrollbars they look different.
| Prop | Value | SLDS | Notes |
|---|---|---|---|
orientation | vertical | slds-scrollable_y | SLDS leaves the browser's scrollbar; this one is drawn from tokens. |
orientation | horizontal | slds-scrollable_x |
Accessibility
- The area has no role and no name. Pass
role="region"and anaria-labelto make it a landmark people can jump to. - The area itself isn't always focusable. Put a link or a control inside, so keyboard users can reach the content; the browser's scrolling keys work once something inside has focus.
Responsive behavior
- The area is the size you give it. Text wraps unless you set
whitespace-nowrap, as the Horizontal example does.
Rules
- Give the area a fixed height, a fixed width, or both. Without one, nothing scrolls.
- Draw the box with
rounded-(--radius-2) border. Don't style the scrollbar or thumb. - Don't put
Tableinside. It wraps the table in its own scrolling box, which scrolls instead of the area. Use a plaintablewith the Table parts, as the Both directions example shows. - Don't use
truncateinside. Give children a fixed width or let text wrap.