Scroll Area
Custom scrollable container with styled scrollbars
The scroll area is a container with custom-styled scrollbars and optional edge fades. Use it for any overflowing region, like a sidebar, a chat log, or a long form, where the native scrollbar would look out of place.
Preview
Installation
Usage
Examples
Fade Edges
Use fadeEdges to add a CSS-mask fade at the edges that appears only where content is scrollable.
The fade depth defaults to min(12%, 2.5rem), 12% of the container capped at 2.5rem so tall scrollers stay subtle. Tune it per instance by setting the --scroll-fade-size CSS variable on viewportClassName:
With nativeScroll, the fade eases in and out over a fixed scroll distance (6rem by default, clamped to the scroll range so short scrollers still fully reveal). Adjust it with --scroll-fade-reveal:
Native Scroll Fade
Add nativeScroll to drive the fade with CSS scroll-driven animations instead of Base UI's measured overflow, falling back to a static fade where unsupported.
Scroll Fade Without the Component
The same edge fade ships as a standalone CSS utility you can drop on any element with overflow, for scroll containers you didn't render with ScrollArea such as a code block, a table wrapper, or a third-party list. See Scroll Fade.
Scrollbar Gutter
Use scrollbarGutter to reserve space for the scrollbar so it doesn't shift the layout when it appears.
Without gutter
With gutter
Persistent Scrollbar
Use persistScrollbar to always show the scrollbar instead of fading it in on hover or scroll.
Horizontal Scroll
Let wide content scroll sideways instead of wrapping.
Both Scrollbars
When content overflows in both directions, both scrollbars appear automatically and the corner keeps them from intersecting.
Fill Content Height
The content wrapper is only as tall as its children, so a short flex column has no slack for mt-auto to work with and a pinned footer floats up under the nav. Set contentHeight="fill" to stretch the wrapper to at least the viewport height and give that footer somewhere to sit.
auto
fill
fill, overflowing
Children of a filled wrapper claim the height with flex-1:
Use flex-1 rather than h-full. A percentage height resolves against the wrapper's own height, which stays growable, so h-full collapses to nothing here.
The wrapper only ever grows from the viewport height, never locks to it, so long content still scrolls normally and keeps its natural size. Leave contentHeight at "auto" for lists, menus, and dialog bodies, where nothing needs to be pushed to the bottom.
Content Width
contentMinWidth decides how wide the internal content wrapper may grow. It defaults to "viewport", which keeps the wrapper at the visible width.
The alternative, "fit-content", is Base UI's own default and lets the wrapper grow to its widest child. That sounds harmless but it switches on intrinsic sizing, and anything in the subtree that physically cannot shrink reports its full width upward. A whitespace-pre code block is the usual culprit. Nesting it in its own scroll area does not help, because a scroll container still passes its content's width up to whatever is measuring it.
The result is a panel meant to scroll vertically that quietly grows a horizontal scrollbar, with the nested scroller stretched wide enough that it never overflows and so never scrolls on its own:
Under "viewport" the wrapper stays put and the code block scrolls inside its own box, which is what you want.
Sideways scrolling still works under "viewport". Children that overflow keep extending the scroll range, so anything sizing itself with w-max, a fixed grid template, or a table's own width behaves exactly as it did before:
What "viewport" gives up is the wrapper stretching across the whole scroll range. Padding on a child lands at the fold instead of the far end, so a horizontally scrolling child with its own padding loses that breathing room at the end of the scroll. Give the child an explicit width to get it back, or switch to "fit-content":
API Reference
The ScrollArea component is built on top of Base UI's ScrollArea. All Base UI props are supported. The documentation below only covers custom props and modified defaults specific to our implementation.
For the complete Base UI API, see the Base UI ScrollArea documentation.
Props
ScrollArea
Container with styled scrollbars and optional fade effects. Wraps Base UI's ScrollArea.Root.