Marble UI
← Components

Scroll Area

Preview: Vertical

Native scrolling with slim overlay scrollbars (Base UI Scroll Area).

Import

import { ScrollArea } from '@marbleui/ui'

Props

<ScrollArea>

PropTypeDefaultDescription
children *requiredReactNode—
classNamestring—
fadeboolean—Fade the content edges while more content is available.
orientation'vertical' | 'horizontal' | 'both''vertical'Which scrollbars to render.
viewportClassNamestring—

Accessibility

Keyboard interaction, focus management and ARIA semantics come from the underlying primitive: Base UI ScrollArea. Follow the primitive's docs for the full keyboard map.

Usage notes

Scrollable region with slim overlay scrollbars that show on hover or while scrolling. For a plain page-level scroll use normal overflow; for a scrollable list of options, ListBox already scrolls.

<ScrollArea className="h-64 w-56 rounded-lg border border-border">
  <div className="p-3">{items}</div>
</ScrollArea>
  • Give the root a fixed className height (vertical) or width (horizontal); without a constraint there is nothing to scroll.
  • orientation is vertical (default), horizontal or both. Horizontal content needs to be wider than the root, e.g. w-max.
  • fade masks the top and bottom edges while more content is available; it applies to vertical overflow only.
  • The viewport is focusable with a visible focus outline, so keyboard users can scroll it.
Example source · show
import { ScrollArea } from './scroll-area'

const tags = Array.from({ length: 40 }, (_, i) => `v1.${40 - i}.0`)

export const styles = {
  Vertical: () => (
    <ScrollArea className="h-64 w-56 rounded-lg border border-border bg-surface">
      <div className="p-3">
        <div className="mb-2 text-sm font-medium text-fg">Releases</div>
        {tags.map((t) => (
          <div key={t} className="border-b border-border py-1.5 text-sm text-fg-muted last:border-0">{t}</div>
        ))}
      </div>
    </ScrollArea>
  ),
  Horizontal: () => (
    <ScrollArea orientation="horizontal" className="w-96 rounded-lg border border-border bg-surface">
      <div className="flex w-max gap-3 p-3">
        {Array.from({ length: 12 }, (_, i) => (
          <div key={i} className="grid size-24 shrink-0 place-items-center rounded-md bg-surface-sunken text-sm text-fg-muted">
            {i + 1}
          </div>
        ))}
      </div>
    </ScrollArea>
  ),
  Fade: () => (
    <ScrollArea fade className="h-56 w-80 rounded-lg border border-border bg-surface">
      <div className="space-y-3 p-4 text-sm leading-relaxed text-fg-muted">
        {Array.from({ length: 8 }, (_, i) => (
          <p key={i}>Paragraph {i + 1}. The edges fade while there is more to scroll, and the scrollbar only appears on hover or scroll.</p>
        ))}
      </div>
    </ScrollArea>
  ),
}

Source: packages/ui/src/scroll-area/scroll-area.tsx

Catalog

Category
layout
Priority
Foundation
Primitive
base-ui
Base UI
Scroll Area