suiss/ui
  • Docs
  • Components
  • Patterns
  • Interactions
  • Charts
  • Blocks
GitHubGet started
DocsComponentsPatternsInteractionsChartsBlocks
Components82
  • Overview
  • Accordion
  • Alert
  • Alert Dialog
  • Alert Sheet
  • Amount Input
  • Aspect Ratio
  • Attachment
  • Avatar
  • Badge
  • Bottom Bar
  • Breadcrumb
  • Bubble
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Chip
  • Collapsible
  • Combobox
  • Command
  • Context Menu
  • Dialog
  • Direction
  • Drawer
  • Dropdown Menu
  • Empty
  • FAB
  • Field
  • Fullscreen Menu
  • Haptics
  • Header
  • Hover Card
  • Icon
  • Input
  • Input Accessory Bar
  • Input Group
  • Input OTP
  • Item
  • Kbd
  • Keyboard Scroll View
  • Keypad
  • Label
  • Marker
  • Menubar
  • Message
  • Message Scroller
  • Native Select
  • Navigation Menu
  • Page Indicator
  • Pagination
  • Pin Pad
  • Popover
  • Progress
  • QR Scanner
  • Questionnaire
  • Radio Group
  • Resizable
  • Screen
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Signature Pad
  • Skeleton
  • Slider
  • Spinner
  • Switch
  • Tab Bar
  • Table
  • Tabs
  • Text
  • Textarea
  • Toast
  • Toggle
  • Toggle Group
  • Tooltip
  • Wheel Picker
  • Widget

suiss/ui · Component

Scroll Area

A scrollable region with slim, custom-styled scrollbars.

Scroll Area is an open-source component from suiss/ui for React. The @esuiss/ui CLI copies its source into your project, so you own the code.

import { ScrollArea } from "@/components/ui/scroll-area"
import { Separator } from "@/components/ui/separator"

const releases = Array.from({ length: 40 }, (_, index) => `v2.${40 - index}.0`)

export default function ScrollAreaDemo() {
  return (
    <ScrollArea className="h-72 w-48 rounded-2xl border">
      <div className="p-4">
        <h4 className="mb-4 text-sm font-medium">Releases</h4>
        {releases.map((release) => (
          <div key={release}>
            <div className="text-sm">{release}</div>
            <Separator className="my-2" />
          </div>
        ))}
      </div>
    </ScrollArea>
  )
}

Scroll Area wraps the scroll area primitive of the chosen base. ScrollArea renders the root, a focusable viewport for your content, a vertical ScrollBar and a corner. Add a horizontal ScrollBar as a child when content scrolls sideways.

Use Scroll Area to give overflowing content a consistent scrollbar across platforms. For chat transcripts that should open at the latest message, use Message Scroller.

Installation

CLI

$ pnpm dlx shadcn@latest add @esuiss/scroll-area

Works in any project with a components.json. See Installation for the one-line registry setup. Or use the suiss/ui CLI:

$ pnpm dlx @esuiss/ui@latest add scroll-area

Manual

  1. Install the dependencies and add the cn helper:
$ pnpm add @base-ui/react
  1. Copy the source into components/ui/scroll-area.tsx:
  1. Update the import paths to match your project.

Usage

import { ScrollArea, ScrollBar } 
<ScrollArea









Give ScrollArea a fixed height or width with className so its content can overflow. Children render inside the viewport. For horizontal scrolling, make the content wider than the area (for example with w-max) and include ScrollBar with orientation="horizontal".

Examples

Horizontal

A row of album covers that scrolls sideways with a horizontal scrollbar.

API Reference

Anatomy2 parts
<ScrollArea>
<ScrollBar />
</ScrollArea>
01

ScrollArea

The root that renders the viewport, the vertical scrollbar and the corner.

Also accepts the props of the primitive part it wraps.

02

ScrollBar

A scrollbar track and thumb for one orientation, vertical by default.

Also accepts the props of the primitive part it wraps.

Accessibility

  • The viewport is focusable, so keyboard users can Tab to it and scroll with the arrow keys.
  • Focus is shown with the standard focus ring around the viewport.
  • The custom scrollbars are presentational; native scrolling by wheel, touch and keyboard still works.

Notes

  • Styling hooks: data-slot values scroll-area, scroll-area-viewport, scroll-area-scrollbar and scroll-area-thumb. Scrollbars expose data-orientation.
  • The thumb uses the border color.
  • The viewport inherits the root's border radius, so rounded containers clip their content.
NextSelectPreviousScreen

On this page

  1. 01Installation
    • CLI
    • Manual
  2. 02Usage
  3. 03Examples
    • Horizontal
  4. 04API Reference
    • ScrollArea
    • ScrollBar
  5. 05Accessibility
  6. 06Notes
from
"@/components/ui/scroll-area"
className
=
"h-72 w-48 rounded-2xl border"
>
<div className="p-4">
<h4 className="mb-4 text-sm font-medium">Releases</h4>
{releases.map((release) => (
<div key={release}>
<div className="text-sm">{release}</div>
<Separator className="my-2" />
</div>
))}
</div>
</ScrollArea>
components/ui/scroll-area.tsx
"use client"

import { ScrollArea as ScrollAreaPrimitive } from "@base-ui/react/scroll-area"
import { cn } from "@/lib/utils"

function ScrollArea({
  className,
  children,
  ...props
}: ScrollAreaPrimitive.Root.Props) {
  return (
    <ScrollAreaPrimitive.Root
      data-slot="scroll-area"
      className={cn("relative", className)}
      {...props}
    >
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"

const albums = [
  { title: "Morning Light", artist: "Nora Hale" },
  { title: "Open Roads", artist: "The Fieldnotes" },
  { title: "Paper Moons", artist: "Ivy Grant" },
  { title: "Low Tide", artist: "Harbor Lines" },
  { title: "Glass Garden", artist: "Mira Stone" },
  { title: "Northbound", artist: "Echo Park" },
  { title: "Slow Motion", artist: "Luca Reyes" },
]

export default function ScrollAreaHorizontal() {
  return (
    <ScrollArea className="w-96 rounded-2xl border whitespace-nowrap">
      <div className="flex w-max gap-4 p-4">
        {albums.map((album) => (
          <figure key={album.title} className="w-32 shrink-0">
            <div className="bg-muted aspect-square rounded-xl" />
            <figcaption className="text-muted-foreground pt-2 text-xs">
              <span className="text-foreground font-medium">{album.title}</span>
              <br />
              {album.artist}
            </figcaption>
          </figure>
        ))}
      </div>
      <ScrollBar orientation="horizontal" />
    </ScrollArea>
  )
}