Skip to main content

Overview

Scroll Area provides custom, cross-browser styled scrollbars while maintaining native scroll behavior.

Features

  • Scrollbar sits on top of the scrollable content
  • Scrolling is native; no underlying position changes
  • Custom cross-browser styling
  • Supports both horizontal and vertical scrolling
  • Supports automatic hiding of scrollbars

Installation

npm install @radix-ui/react-scroll-area

Anatomy

import * as ScrollArea from '@radix-ui/react-scroll-area';

export default () => (
  <ScrollArea.Root>
    <ScrollArea.Viewport />
    <ScrollArea.Scrollbar orientation="vertical">
      <ScrollArea.Thumb />
    </ScrollArea.Scrollbar>
    <ScrollArea.Scrollbar orientation="horizontal">
      <ScrollArea.Thumb />
    </ScrollArea.Scrollbar>
    <ScrollArea.Corner />
  </ScrollArea.Root>
)

API Reference

Root

Contains all the parts of a scroll area.
type
'auto' | 'always' | 'scroll' | 'hover'
default:"'hover'"
Describes the nature of scrollbar visibility.
  • auto - Scrollbars are visible when content overflows
  • always - Scrollbars are always visible
  • scroll - Scrollbars are visible when scrolling
  • hover - Scrollbars are visible when hovering over the scroll area
scrollHideDelay
number
default:"600"
Time in milliseconds before the scrollbars hide after the user stops interacting with scrollbars.
dir
'ltr' | 'rtl'
The reading direction of the scroll area. If omitted, inherits globally from DirectionProvider or assumes LTR.

Viewport

The viewport area of the scroll area.

Scrollbar

The vertical or horizontal scrollbar.
orientation
'vertical' | 'horizontal'
default:"'vertical'"
The orientation of the scrollbar.
forceMount
boolean
Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries.

Thumb

The thumb to be used in a scrollbar.

Corner

The corner where both vertical and horizontal scrollbars meet.

Examples

Basic Usage

import * as ScrollArea from '@radix-ui/react-scroll-area';

export default () => (
  <ScrollArea.Root style={{ width: 200, height: 225 }}>
    <ScrollArea.Viewport style={{ width: '100%', height: '100%' }}>
      <div style={{ padding: 15 }}>
        {Array.from({ length: 50 }, (_, i) => (
          <div key={i}>Item {i + 1}</div>
        ))}
      </div>
    </ScrollArea.Viewport>
    <ScrollArea.Scrollbar orientation="vertical">
      <ScrollArea.Thumb />
    </ScrollArea.Scrollbar>
    <ScrollArea.Scrollbar orientation="horizontal">
      <ScrollArea.Thumb />
    </ScrollArea.Scrollbar>
    <ScrollArea.Corner />
  </ScrollArea.Root>
);

Always Visible

import * as ScrollArea from '@radix-ui/react-scroll-area';

export default () => (
  <ScrollArea.Root type="always" style={{ width: 200, height: 225 }}>
    <ScrollArea.Viewport style={{ width: '100%', height: '100%' }}>
      <div style={{ padding: 15 }}>
        Content that overflows...
      </div>
    </ScrollArea.Viewport>
    <ScrollArea.Scrollbar orientation="vertical">
      <ScrollArea.Thumb />
    </ScrollArea.Scrollbar>
  </ScrollArea.Root>
);

Data Attributes

Scrollbar

  • data-state - "visible" or "hidden"
  • data-orientation - "vertical" or "horizontal"

Thumb

  • data-state - "visible" or "hidden"

CSS Variables

Root

  • --radix-scroll-area-corner-width - The width of the corner
  • --radix-scroll-area-corner-height - The height of the corner

Build docs developers (and LLMs) love