shadcn.io is not affiliated with official shadcn/ui
Shadcn Scroll Area for React and Tailwind
Custom scrollable area with styled scrollbars.
Tags
v1.0.0-beta.0
v1.0.0-beta.1
v1.0.0-beta.2
v1.0.0-beta.3
v1.0.0-beta.4
v1.0.0-beta.5
v1.0.0-beta.6
v1.0.0-beta.7
v1.0.0-beta.8
v1.0.0-beta.9
v1.0.0-beta.10
v1.0.0-beta.11
v1.0.0-beta.12
v1.0.0-beta.13
v1.0.0-beta.14
v1.0.0-beta.15
v1.0.0-beta.16
v1.0.0-beta.17
v1.0.0-beta.18
v1.0.0-beta.19
v1.0.0-beta.20
v1.0.0-beta.21
v1.0.0-beta.22
v1.0.0-beta.23
v1.0.0-beta.24
v1.0.0-beta.25
v1.0.0-beta.26
v1.0.0-beta.27
v1.0.0-beta.28
v1.0.0-beta.29
v1.0.0-beta.30
v1.0.0-beta.31
v1.0.0-beta.32
v1.0.0-beta.33
v1.0.0-beta.34
v1.0.0-beta.35
v1.0.0-beta.36
v1.0.0-beta.37
v1.0.0-beta.38
v1.0.0-beta.39
v1.0.0-beta.40
v1.0.0-beta.41
v1.0.0-beta.42
v1.0.0-beta.43
v1.0.0-beta.44
v1.0.0-beta.45
v1.0.0-beta.46
v1.0.0-beta.47
v1.0.0-beta.48
v1.0.0-beta.49
Installation
bunx --bun shadcn@latest add https://kit.dev/r/scroll-area.jsonpnpm dlx shadcn@latest add https://kit.dev/r/scroll-area.jsonnpx shadcn@latest add https://kit.dev/r/scroll-area.jsonyarn shadcn@latest add https://kit.dev/r/scroll-area.jsonInstall the following dependencies:
bun add @ark-ui/react tailwind-variantspnpm add @ark-ui/react tailwind-variantsnpm install @ark-ui/react tailwind-variantsyarn add @ark-ui/react tailwind-variantsCopy and paste the following code into your project.
"use client";
import {
ScrollArea as ArkScrollArea,
useScrollAreaContext,
} from "@ark-ui/react/scroll-area";
import type React from "react";
import { tv, type VariantProps } from "tailwind-variants";
import { cn } from "@/lib/utils";
export const useScrollArea = useScrollAreaContext;
const scrollAreaVariants = tv({
base: [
"h-full",
"rounded-[inherit]",
"outline-none",
"scrollbar-none",
"outline-none",
],
variants: {
scrollFade: {
true: [
"data-overflow-y:not-data-at-top:mask-t-from-[calc(100%-var(--fade-size))]",
"data-overflow-y:not-data-at-bottom:mask-b-from-[calc(100%-var(--fade-size))]",
"transition-shadow",
"motion-reduce:transition-none!",
],
},
},
defaultVariants: {
scrollFade: false,
},
});
interface ScrollAreaProps
extends React.ComponentProps<typeof ArkScrollArea.Root>,
VariantProps<typeof scrollAreaVariants> {}
export const ScrollArea = (props: ScrollAreaProps) => {
const { scrollFade = false, className, children, ...rest } = props;
return (
<ArkScrollArea.Root
className={cn("size-full min-h-0 [--fade-size:1.5rem]", className)}
data-slot="scroll-area"
{...rest}
>
<ArkScrollArea.Viewport
className={cn(scrollAreaVariants({ scrollFade }))}
data-slot="scroll-area-viewport"
>
<ArkScrollArea.Content data-slot="scroll-area-content">
{children}
</ArkScrollArea.Content>
</ArkScrollArea.Viewport>
<ScrollAreaScrollbar orientation="vertical" />
<ScrollAreaScrollbar orientation="horizontal" />
<ArkScrollArea.Corner data-slot="scroll-area-corner" />
</ArkScrollArea.Root>
);
};
export const ScrollAreaScrollbar = (
props: React.ComponentProps<typeof ArkScrollArea.Scrollbar>
) => {
const { orientation, className, ...rest } = props;
return (
<ArkScrollArea.Scrollbar
className={cn(
"flex",
"m-1",
"bg-transparent",
"opacity-0 transition-opacity delay-300",
"data-[orientation=vertical]:w-1.5",
"data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:flex-col",
"data-hover:opacity-100 data-hover:delay-0 data-hover:duration-100",
"data-scrolling:opacity-100 data-scrolling:delay-0 data-scrolling:duration-100",
"data-[orientation=vertical]:in-[[data-slot=scroll-area]:not([data-overflow-y])]:hidden",
"data-[orientation=horizontal]:in-[[data-slot=scroll-area]:not([data-overflow-x])]:hidden",
"motion-reduce:transition-none!",
className
)}
data-slot="scroll-area-scrollbar"
orientation={orientation}
{...rest}
>
<ArkScrollArea.Thumb
className="relative flex-1 rounded-full bg-foreground/20"
data-slot="scroll-area-thumb"
/>
</ArkScrollArea.Scrollbar>
);
};Update the import paths to match your project setup.
Anatomy
ScrollArea
├── ScrollAreaViewport
├── ScrollAreaContent
├── ScrollAreaScrollbar
│ └── ScrollAreaThumb
└── ScrollAreaCornerUsage
import React from "react";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";const tags = Array.from({ length: 50 }, (_, i) => `v1.0.0-beta.${i}`);
const ScrollAreaDemo = () => (
<ScrollArea className="h-64 w-48 rounded-md border">
<div className="p-4">
<h4 className="mb-4 font-medium text-sm leading-none">Tags</h4>
{tags.map((tag) => (
<React.Fragment key={tag}>
<div className="text-sm">{tag}</div>
<Separator className="my-2" />
</React.Fragment>
))}
</div>
</ScrollArea>
);Accessibility
| Key | Description |
|---|---|
Enter | Activate the focused item. |
Demos
Both Directions
Horizontal
Nested
Scroll Fade
API Reference
ScrollArea
div
PropType
AttributeType
CSS variableType
ScrollAreaViewport
div
PropType
ScrollAreaContent
div
PropType
ScrollAreaScrollbar
div
PropType
AttributeType
ScrollAreaThumb
div
PropType
ScrollAreaCorner
div
PropType