# Scroll Area

**A native scroll container with custom scrollbars.**

**Reference:** [View Source](https://github.com/jramke/fluid-primitives/tree/main/Resources/Private/Primitives/ScrollArea) · [Zag.js Docs](https://zagjs.com/components/react/scroll-area)

**ScrollArea.html**

```html
<ui:scrollArea.root class="h-50 max-w-90">
    <ui:scrollArea.viewport class="border rounded-md">
        <ui:scrollArea.content>
            <div class="py-3 pr-6 pl-4 text-sm leading-relaxed">
                <p>
                    Fugiat adipisicing dolor ut irure. Ut aute Lorem labore est aute quis officia quis consectetur in amet id velit dolore. Occaecat labore adipisicing nostrud veniam. Eu non tempor ipsum. Sunt irure enim enim sint magna laboris ex tempor excepteur nulla est amet culpa.
                </p>
                <p class="mt-4">
                    Est nulla commodo laboris velit ipsum dolore. Magna id anim Lorem labore minim aute irure laboris. Velit elit duis exercitation duis mollit enim cupidatat consectetur mollit non officia deserunt fugiat do deserunt.
                </p>
            </div>
        </ui:scrollArea.content>
    </ui:scrollArea.viewport>
    <ui:scrollArea.scrollbar>
        <ui:scrollArea.thumb />
    </ui:scrollArea.scrollbar>
</ui:scrollArea.root>

```

**ScrollArea.ts**

```ts
import { mountAll } from 'fluid-primitives';
import { ScrollArea } from 'fluid-primitives/scroll-area';

mountAll('scrollArea', ({ props }) => {
    const scrollArea = new ScrollArea(props);
    scrollArea.init();
    return scrollArea;
});

```

## Features

- Uses native browser scrolling for performance
- Supports vertical and horizontal scrolling
- Customizable scrollbar appearance
- Supports visibility modes: always, scroll, or hover
- Scrollbar thumb reflects the actual scroll position

## Installation

```bash
typo3 ui:add scroll-area
```

Or copy the files manually from GitHub (https://github.com/jramke/fluid-primitives.com/tree/main/packages/docs/Resources/Private/Registry/ScrollArea) into your project.

Read more about installing [Components and Primitives](/docs/core-concepts/primitives.md).

## Examples

### Horizontal Scroll

Enable horizontal scrolling for wide content.

**ScrollArea.html**

```html
<ui:scrollArea.root class="w-96">
    <ui:scrollArea.viewport class="border rounded-md">
        <ui:scrollArea.content class="flex gap-4 w-max p-4">
            <div class="w-48 h-32 bg-muted rounded grid place-items-center">Item 1</div>
            <div class="w-48 h-32 bg-muted rounded grid place-items-center">Item 2</div>
            <div class="w-48 h-32 bg-muted rounded grid place-items-center">Item 3</div>
            <div class="w-48 h-32 bg-muted rounded grid place-items-center">Item 4</div>
        </ui:scrollArea.content>
    </ui:scrollArea.viewport>
    <ui:scrollArea.scrollbar orientation="{f:constant(name: 'Jramke\FluidPrimitives\Enum\Orientation::Horizontal')}">
        <ui:scrollArea.thumb />
    </ui:scrollArea.scrollbar>
</ui:scrollArea.root>

```

### Both Directions

Support scrolling in both vertical and horizontal directions.

**ScrollArea.html**

```html
<ui:scrollArea.root class="h-72 w-72">
    <ui:scrollArea.viewport class="border rounded-md">
        <ui:scrollArea.content class="w-[500px] h-[500px] p-4">
            <p class="text-sm">Large content that scrolls in both directions.</p>
            <div class="mt-4 grid grid-cols-3 gap-4">
                <div class="w-32 h-32 bg-muted rounded"></div>
                <div class="w-32 h-32 bg-muted rounded"></div>
                <div class="w-32 h-32 bg-muted rounded"></div>
                <div class="w-32 h-32 bg-muted rounded"></div>
                <div class="w-32 h-32 bg-muted rounded"></div>
                <div class="w-32 h-32 bg-muted rounded"></div>
                <div class="w-32 h-32 bg-muted rounded"></div>
                <div class="w-32 h-32 bg-muted rounded"></div>
                <div class="w-32 h-32 bg-muted rounded"></div>
            </div>
        </ui:scrollArea.content>
    </ui:scrollArea.viewport>
    <ui:scrollArea.scrollbar orientation="{f:constant(name: 'Jramke\FluidPrimitives\Enum\Orientation::Vertical')}">
        <ui:scrollArea.thumb />
    </ui:scrollArea.scrollbar>
    <ui:scrollArea.scrollbar orientation="{f:constant(name: 'Jramke\FluidPrimitives\Enum\Orientation::Horizontal')}">
        <ui:scrollArea.thumb />
    </ui:scrollArea.scrollbar>
</ui:scrollArea.root>

```

## API Reference

### scrollArea.root

Provides the scroll area container and shared state. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `rootId` | `string` | No | `-` | The root ID of the component, used for hydration and identification. |
| `ids` | `array` | No | `[]` | The IDs of of the component parts for composition. |
| `controlled` | `boolean` | No | `false` | If true, the component is meant to be initialized manually inside another component |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-scope` | scroll-area |
| `data-part` | root |
| `data-overflow-x` | Present when the content overflows the x-axis |
| `data-overflow-y` | Present when the content overflows the y-axis |

### scrollArea.viewport

Provides the native scrollable viewport. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-scope` | scroll-area |
| `data-part` | viewport |
| `data-at-top` | Present when scrolled to the top edge |
| `data-at-bottom` | Present when scrolled to the bottom edge |
| `data-at-left` | Present when scrolled to the left edge |
| `data-at-right` | Present when scrolled to the right edge |
| `data-overflow-x` | Present when the content overflows the x-axis |
| `data-overflow-y` | Present when the content overflows the y-axis |

### scrollArea.content

Wraps the scrollable content to measure its size. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-scope` | scroll-area |
| `data-part` | content |
| `data-overflow-x` | Present when the content overflows the x-axis |
| `data-overflow-y` | Present when the content overflows the y-axis |

### scrollArea.scrollbar

Displays a custom scrollbar track. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `orientation` | `Enum\Orientation` | No | `Vertical` | The orientation of the scrollbar. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-scope` | scroll-area |
| `data-part` | scrollbar |
| `data-orientation` | The orientation of the scrollbar |
| `data-scrolling` | Present when scrolling |
| `data-hover` | Present when hovered |
| `data-dragging` | Present when in the dragging state |
| `data-overflow-x` | Present when the content overflows the x-axis |
| `data-overflow-y` | Present when the content overflows the y-axis |

### scrollArea.thumb

Displays the draggable scrollbar thumb. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-scope` | scroll-area |
| `data-part` | thumb |
| `data-orientation` | The orientation of the thumb |
| `data-hover` | Present when hovered |
| `data-dragging` | Present when in the dragging state |

### Machine JavaScript API

| Name | Type | Description |
| --- | --- | --- |
| `isAtTop` | `boolean` | Whether the scroll area is at the top |
| `isAtBottom` | `boolean` | Whether the scroll area is at the bottom |
| `isAtLeft` | `boolean` | Whether the scroll area is at the left |
| `isAtRight` | `boolean` | Whether the scroll area is at the right |
| `hasOverflowX` | `boolean` | Whether the scroll area has horizontal overflow |
| `hasOverflowY` | `boolean` | Whether the scroll area has vertical overflow |
| `getScrollProgress` | `() => Point` | Get the scroll progress as values between 0 and 1 |
| `scrollToEdge` | `(details: ScrollToEdgeDetails) => void` | Scroll to the edge of the scroll area |
| `scrollTo` | `(details: ScrollToDetails) => void` | Scroll to specific coordinates |
| `getScrollbarState` | `(props: ScrollbarProps) => ScrollbarState` | Returns the state of the scrollbar |

## Anatomy

```html
<primitives:scrollArea.root>
    <primitives:scrollArea.viewport>
        <primitives:scrollArea.content />
    </primitives:scrollArea.viewport>
    <primitives:scrollArea.scrollbar>
        <primitives:scrollArea.thumb />
    </primitives:scrollArea.scrollbar>
</primitives:scrollArea.root>
```
