Scroll Area
Augments native scroll functionality for custom, cross-browser styling. Built for React applications with Next.js integration and TypeScript support.
You know how scrollbars look different on every OS and browser? Mac has those disappearing ones, Windows has the chunky ones, and don't even get me started on mobile. ScrollArea fixes that - consistent, styled scrollbars everywhere.
Vertical scrolling with custom scrollbar
Clean scrollbar that matches your design:
Built on Radix UI ScrollArea with native scrolling behavior preserved. This free open source React component gives you styled scrollbars without breaking keyboard navigation, touch scrolling, or any of the native stuff people expect.
npx shadcn@latest add scroll-area
Why custom scrollbars matter
Default scrollbars can ruin a carefully designed interface. ScrollArea lets you fix that:
- Consistent everywhere - Same look on Mac, Windows, Linux, mobile
- Native behavior - All the keyboard and touch stuff still works
- No layout shift - Scrollbar overlays content, doesn't push it
- Auto-hide options - Show on hover, always visible, your choice
- Performance first - Uses native scrolling, no janky transforms
- RTL ready - Works properly with right-to-left layouts
Useful scroll area patterns
Horizontal gallery
Perfect for image carousels and media galleries:
Chat messages
Scrollable message history that stays at the bottom:
Code viewer
Syntax highlighted code with both scrollbars:
These patterns solve real problems. Image galleries that don't break on mobile, chat interfaces that feel native, code viewers that handle long lines properly.
Perfect for constrained spaces
Works great anywhere you need scrolling in a fixed area - sidebars, modals, chat windows, dropdown menus, data tables. The kind of places where you need control over how scrolling looks and feels.
Drops right into Next.js projects. Full TypeScript support. Styled with Tailwind CSS to match the shadcn design system.
Built on Radix UI
Uses Radix UI ScrollArea under the hood, which does it right:
- Overlay scrollbars - Don't take up space in your layout
- Native scrolling - No weird JS-powered scrolling
- Pointer behavior - Only intercepts when dragging scrollbar
- Keyboard unaffected - Page Up/Down, arrows all work normally
- Touch friendly - Swipe scrolling works as expected
- Corner piece - That little square where scrollbars meet
API Reference
ScrollArea
The root container that wraps scrollable content.
Prop | Type | Default | Description |
---|---|---|---|
className | string | - | Additional CSS classes |
type | "auto" | "always" | "scroll" | "hover" | "hover" | Scrollbar visibility behavior |
scrollHideDelay | number | 600 | Hide delay in ms for hover type |
dir | "ltr" | "rtl" | "ltr" | Reading direction |
ScrollBar
The scrollbar component (imported separately when needed).
Prop | Type | Default | Description |
---|---|---|---|
className | string | - | Additional CSS classes |
orientation | "vertical" | "horizontal" | "vertical" | Scrollbar direction |
Data attributes:
[data-state]
: "visible" | "hidden"[data-orientation]
: "vertical" | "horizontal"
Visibility Types
Type | Behavior | Use Case |
---|---|---|
"auto" | Show when content overflows | Default browser behavior |
"always" | Always visible | When users need to see scroll position |
"scroll" | Visible while scrolling | Clean look with feedback |
"hover" | Visible on hover | Maximum content space |
Common Patterns
Pattern | Use Case | Implementation |
---|---|---|
Fixed height list | Sidebar navigation | Set height on ScrollArea |
Horizontal scroll | Image gallery | Add ScrollBar with horizontal orientation |
Both scrollbars | Data tables, code | Add both vertical and horizontal ScrollBar |
Chat container | Message lists | ScrollArea with auto-scroll to bottom |
Modal content | Long forms | ScrollArea inside dialog |
Styling Scrollbars
The scrollbar can be styled with Tailwind classes:
<ScrollArea className="h-[200px]">
{/* Content */}
<ScrollBar className="w-2.5" /> {/* Thin scrollbar */}
</ScrollArea>
Make scrolling feel right
Few things to keep in mind:
- Set explicit height - ScrollArea needs a height to know when to scroll
- Consider mobile - Touch users don't see scrollbars until they scroll
- Add padding - Content shouldn't touch the edges
- Mind the corner - Where scrollbars meet can look weird
- Test with long content - Make sure it handles edge cases
- Preserve scroll position - Important for chat and infinite lists
- Show scroll hints - Shadows or gradients can indicate more content
- Respect preferences - Some users need scrollbars always visible
Resizable
Accessible resizable panel groups and layouts with keyboard support. Built for React applications with Next.js integration and TypeScript support.
Select
Displays a list of options for the user to pick from—triggered by a button. Built for React applications with Next.js integration and TypeScript support.