For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. An agent skill is available at /.well-known/agent-skills/site-skill.md.
Home

Scroll Area

A custom-styled scrollable container with a thin overlay scrollbar for both vertical and horizontal overflow.

Tags

Component 1

Component 2

Component 3

Component 4

Component 5

Component 6

Component 7

Component 8

Component 9

Component 10

Component 11

Component 12

Component 13

Component 14

Component 15

Component 16

Component 17

Component 18

Component 19

Component 20

Component 21

Component 22

Component 23

Component 24

Component 25

Component 26

Component 27

Component 28

Component 29

Component 30

Component 31

Component 32

Component 33

Component 34

Component 35

Component 36

Component 37

Component 38

Component 39

Component 40

Component 41

Component 42

Component 43

Component 44

Component 45

Component 46

Component 47

Component 48

Component 49

Component 50

OrnithologyCharlie Parker
So WhatMiles Davis
Waltz for DebbyBill Evans
A Love SupremeJohn Coltrane
Take FiveDave Brubeck
Kind of BlueMiles Davis
Giant StepsJohn Coltrane
Maiden VoyageHerbie Hancock
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";

const tags = Array.from({ length: 50 }, (_, i) => `Component ${i + 1}`);

const artworks = [
  { artist: "Charlie Parker", title: "Ornithology" },
  { artist: "Miles Davis", title: "So What" },
  { artist: "Bill Evans", title: "Waltz for Debby" },
  { artist: "John Coltrane", title: "A Love Supreme" },
  { artist: "Dave Brubeck", title: "Take Five" },
  { artist: "Miles Davis", title: "Kind of Blue" },
  { artist: "John Coltrane", title: "Giant Steps" },
  { artist: "Herbie Hancock", title: "Maiden Voyage" },
];

export const ScrollAreaDemo = () => (
    <div className="flex gap-6">
      {/* Vertical */}
      <ScrollArea className="h-72 w-48 rounded-md border">
        <div className="p-4">
          <h4 className="mb-4 text-sm font-medium leading-none">Tags</h4>
          {tags.map((tag) => (
            <div key={tag}>
              <p className="text-sm">{tag}</p>
              <Separator className="my-2" />
            </div>
          ))}
        </div>
      </ScrollArea>
      {/* Horizontal */}
      <ScrollArea className="w-64 rounded-md border">
        <div className="flex gap-4 p-4">
          {artworks.map((artwork) => (
            <figure key={artwork.title} className="shrink-0">
              <div className="overflow-hidden rounded-md"><div className="size-[150px] bg-muted" /></div>
              <figcaption className="pt-2 text-xs text-muted-foreground">
                <span className="font-medium text-foreground block truncate w-[150px]">{artwork.title}</span>
                {artwork.artist}
              </figcaption>
            </figure>
          ))}
        </div>
        <ScrollBar orientation="horizontal" />
      </ScrollArea>
    </div>
  );

Horizontal

Add a <ScrollBar orientation="horizontal" /> inside ScrollArea to enable horizontal scrolling. Both scrollbars can coexist.

<ScrollArea className="w-96 rounded-md border whitespace-nowrap">
  <div className="flex gap-4 p-4">
    {items.map((item) => (
      <div key={item} className="shrink-0 w-40 h-20 rounded-md bg-muted" />
    ))}
  </div>
  <ScrollBar orientation="horizontal" />
</ScrollArea>

Fixed height

Always set a fixed height (or max-height) on the ScrollArea — without a constraint the container expands to fit its content and nothing scrolls.

<ScrollArea className="h-64 w-full rounded-md border">
  {/* long content */}
</ScrollArea>

Both axes

Include both ScrollBar components for a two-dimensional scroll area.

<ScrollArea className="h-72 w-96 rounded-md border">
  <div className="w-[600px]">{/* wide + tall content */}</div>
  <ScrollBar orientation="horizontal" />
</ScrollArea>

Props

ScrollArea

Extends all Radix ScrollArea.Root props. Always set a height via className or style — the root is position: relative and the viewport fills it with size-full.

ScrollBar

PropTypeDefaultDescription
orientation"vertical" | "horizontal""vertical"Which axis this scrollbar controls
classNamestring—Merged with the scrollbar track classes

Usage

import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
 
<ScrollArea className="h-72 w-48 rounded-md border">
  <div className="p-4">
    {items.map((item) => (
      <p key={item} className="text-sm py-1">{item}</p>
    ))}
  </div>
</ScrollArea>

Specs

# Mint — Scroll Area Specs
 
## Component
- name: scroll-area
- file: registry/mint/scroll-area.tsx
- installs to: components/ui/scroll-area.tsx
- dependencies: radix-ui
- registryDependencies: none
 
## What is it
A scrollable container that replaces native OS scrollbars with a consistent,
minimal custom design. Use it whenever overflowing content needs to be
scrollable with a predictable scrollbar appearance across platforms. Prefer
it over overflow-auto when visual consistency of the scrollbar track matters.
 
## Visual identity
Thin 2.5-unit (10px) scrollbar track with a transparent border that acts as
padding, giving the thumb a floating feel. The thumb uses --border — a soft,
translucent green tint — for a light touch that works across light and dark
themes without drawing attention.
 
## Design tokens
--border: oklch(0.88 0.04 155 / 60%) / oklch(0.32 0.05 155 / 40%)   — scrollbar thumb colour
--ring:   oklch(0.5 0.14 155) / oklch(0.62 0.15 155)      — green viewport focus ring
 
## Sub-components
- ScrollArea   → Root wrapper; position relative; auto-includes a vertical ScrollBar and Corner
- ScrollBar    → Scrollbar track; 2.5-unit wide (vertical) or tall (horizontal); transparent border acts as inset padding
- (Viewport)   → Internal; fills root with size-full; inherits border-radius; receives focus ring on keyboard scroll
- (Thumb)      → Internal; bg-border, rounded-full; sized by Radix proportional to content ratio
- (Corner)     → Internal; fills the gap when both vertical and horizontal scrollbars are present
 
## States
- focus-visible: viewport receives a 3px ring in --ring colour with ring/50 opacity on keyboard navigation
- data-[state=visible]: Radix shows the scrollbar when content overflows; hidden otherwise
- data-[orientation=vertical]: scrollbar is h-full w-2.5 with border-l
- data-[orientation=horizontal]: scrollbar is h-2.5 flex-col with border-t
 
## Conventions
- ScrollArea must have a constrained height (h-*, max-h-*) or the container expands to fit content and nothing scrolls
- A vertical ScrollBar is auto-rendered inside ScrollArea — do not add a second one
- For horizontal scrolling, add <ScrollBar orientation="horizontal" /> explicitly inside ScrollArea
- For two-axis scrolling, include both orientations; the Corner fills the overlap gap automatically
- Sub-components expose data-slot attributes for CSS targeting: "scroll-area", "scroll-area-viewport", "scroll-area-scrollbar", "scroll-area-thumb"
- Add whitespace-nowrap on the inner container to prevent line wrapping when using horizontal scroll

Installation

GIN Design Plugin
$ npx shadcn add https://gin-design.vercel.app/scroll-area