ScrollArea
Custom scrollable container with styled scrollbars that work across browsers.
Basic
Jokester began sneaking into the castle in the middle of the night and leaving jokes all over the place: under the king's pillow, in his soup, even in the royal toilet.
The king was furious, but he couldn't help but laugh at the jokes. They were actually pretty funny. So, he declared that Jokester would be the official court jester.
And so, Jokester the Wise became the most beloved figure in the kingdom, known far and wide for his hilarious jokes and his ability to make even the grumpiest of kings smile.
The moral of the story? Never underestimate the power of a good laugh, and always be ready to find the humor in any situation.
<VStack className="w-full max-w-sm mx-auto">
<ScrollArea className="h-48 w-full rounded-xl border p-4">
<div className="space-y-4">
<p className="text-sm">
Jokester began sneaking into the castle in the middle of the night and leaving
jokes all over the place: under the king's pillow, in his soup, even in the
royal toilet.
</p>
<p className="text-sm">
The king was furious, but he couldn't help but laugh at the jokes. They were
actually pretty funny. So, he declared that Jokester would be the official
court jester.
</p>
<p className="text-sm">
And so, Jokester the Wise became the most beloved figure in the kingdom, known
far and wide for his hilarious jokes and his ability to make even the grumpiest
of kings smile.
</p>
<p className="text-sm">
The moral of the story? Never underestimate the power of a good laugh, and
always be ready to find the humor in any situation.
</p>
</div>
</ScrollArea>
</VStack> Horizontal scroll
<VStack className="w-full max-w-md mx-auto">
<ScrollArea className="w-full whitespace-nowrap rounded-xl border">
<div className="flex w-max space-x-4 p-4">
{[1, 2, 3, 4, 5, 6, 7, 8].map((i) => (
<div
key={i}
className="shrink-0 w-32 h-24 rounded-lg bg-muted flex items-center justify-center"
>
<span className="text-sm text-muted-foreground">Item {i}</span>
</div>
))}
</div>
<ScrollBar orientation="horizontal" />
</ScrollArea>
</VStack> With list items
Tags
<VStack className="w-full max-w-sm mx-auto">
<ScrollArea className="h-64 w-full rounded-xl border">
<div className="p-4">
<h4 className="mb-4 text-sm font-medium leading-none">Tags</h4>
{tags.map((tag, i, arr) => (
<div key={tag}>
<div className="text-sm py-2">{tag}</div>
{i < arr.length - 1 && <Separator />}
</div>
))}
</div>
</ScrollArea>
</VStack> Both directions
This content is wider and taller than the container, so you can scroll both horizontally and vertically to see all of it.
<VStack className="w-full max-w-sm mx-auto">
<ScrollArea className="h-48 w-full rounded-xl border">
<div className="p-4 w-[500px]">
<p className="text-sm mb-4">
This content is wider and taller than the container, so you can scroll
both horizontally and vertically to see all of it.
</p>
<div className="grid grid-cols-4 gap-4">
{Array.from({ length: 16 }).map((_, i) => (
<div
key={i}
className="h-20 w-24 rounded-lg bg-muted flex items-center justify-center shrink-0"
>
<span className="text-xs text-muted-foreground">{i + 1}</span>
</div>
))}
</div>
</div>
<ScrollBar orientation="horizontal" />
</ScrollArea>
</VStack>