# ScrollableArea

- Page: https://jiguang132.com/resources/astryx/docs/scrollable-area
- Resource: Astryx (https://jiguang132.com/resources/astryx.md)
- All guides: https://jiguang132.com/resources/astryx/docs.md

Provides a native scroll viewport and a real observed content box. The viewport enters the tab order only while a requested logical axis is effectively scrollable, and containment applies only to effective axes.

## Installation

```bash
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
```

Requires React 19+, base CSS and a Theme provider. See [Setup](/resources/astryx/docs/getting-started).

## Scrollable Area

Provides a native scroll viewport and a real observed content box. The viewport enters the tab order only while a requested logical axis is effectively scrollable, and containment applies only to effective axes.

| Prop | Type | Default | Description |
|---|---|---|---|
| axis | 'inline' \| 'block' \| 'both' | 'block' | Logical axis or axes where native scrolling is allowed. |
| label * | string |  | Accessible name for the viewport when it becomes keyboard scrollable. |
| role | 'group' \| 'region' | 'group' | Semantics for the named viewport. |
| overscroll | 'allow' \| 'contain' | 'allow' | Whether effective axes continue scrolling an ancestor at their edge. |
| width | SizeValue |  | Width of the viewport; a number is interpreted as pixels, a string is used as-is. |
| height | SizeValue |  | Height of the viewport; a number is interpreted as pixels, a string is used as-is. |
| maxWidth | SizeValue |  | Maximum width of the viewport. |
| minHeight | SizeValue |  | Minimum height of the viewport. |
| stickyContainment | 'whenScrollable' \| 'always' | 'whenScrollable' | Whether fitting content passes Sticky ownership to an outer container or deliberately keeps this viewport as the CSS Sticky boundary. |
| padding | 0 \| 0.5 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 5 \| 6 \| 8 \| 10 | 0 | Content padding on every logical edge; publishes matching inset geometry. |
| paddingInline | 0 \| 0.5 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 5 \| 6 \| 8 \| 10 |  | Logical inline-axis content padding; overrides `padding` on that axis. |
| paddingInlineStart | 0 \| 0.5 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 5 \| 6 \| 8 \| 10 |  | Logical inline-start content padding; overrides broader padding values. |
| paddingInlineEnd | 0 \| 0.5 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 5 \| 6 \| 8 \| 10 |  | Logical inline-end content padding; overrides broader padding values. |
| paddingBlock | 0 \| 0.5 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 5 \| 6 \| 8 \| 10 |  | Logical block-axis content padding; overrides `padding` on that axis. |
| paddingBlockStart | 0 \| 0.5 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 5 \| 6 \| 8 \| 10 |  | Logical block-start content padding; overrides broader padding values. |
| paddingBlockEnd | 0 \| 0.5 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 5 \| 6 \| 8 \| 10 |  | Logical block-end content padding; overrides broader padding values. |
| isFullBleed | boolean | false | Lets the viewport escape inherited container padding without changing content padding. |
| children | ReactNode |  | Content rendered inside the observed content box. |
| xstyle | StyleXStyles |  | StyleX sizing and native scrollbar presentation overrides for the viewport. |

### Usage guidance

- Give every area a concise label that identifies the content keyboard users will scroll.
- Choose `inline`, `block`, or `both` from content intent; the component maps the logical axes through writing mode and direction.
- Keep the default `overscroll="allow"` for nested areas unless the interaction deliberately needs containment.
- Use `useScrollableArea` instead when a component already owns both a viewport and a suitable content box, or when children must remain direct flex/grid items or retain a definite percentage block-size basis.
- ScrollableArea owns one normal block content box with a 100% minimum size. Inline and both-axis modes use max-content inline sizing, so intrinsic inline layout is intentionally wider than the viewport.
- Use logical padding props on the content box so nested full-bleed components receive the same inset geometry.
- Set `isFullBleed` only when the viewport itself should reach an ancestor container edge; it is off by default.
- Set `stickyContainment="always"` only when a fitting viewport should intentionally remain a Sticky boundary.
- Avoid: Hide the native scrollbar without another visible and operable overflow affordance.
- Avoid: Add another overflow wrapper around ScrollableArea; one native viewport should own scrolling.

### Theming API

```json
{
  "targets": [
    {
      "className": "astryx-scrollable-area",
      "visualProps": [
        "axis"
      ]
    }
  ]
}
```

### Anatomy

- **Viewport**: The root native scroll container, accessible name owner, focus target while effective, and `astryx-scrollable-area` theme target.
- **Content box**: A real inner layout box observed together with the viewport. For inline scrolling it uses max-content inline sizing with a 100% minimum.


## Examples

- Scrollable Area: A fixed-height file panel that scrolls on the block axis; the heading sits inside the viewport, so it scrolls away with the content.
- Scrollable Area — Inline Rail: axis="inline" scrolls the same cards sideways; isFullBleed lets the rail run to the panel edges while the content padding keeps the first card aligned with the heading.
- Scrollable Area — Overscroll: The same section, two edge policies: the default overscroll="allow" hands a gesture that reaches the end to the panel behind it, while overscroll="contain" stops it at the section edge.
- Scrollable Area — Sticky Section Labels: A scrollable viewport is the containing block for position: sticky, so section labels pin to the top edge of the list instead of the page.
- Scrollable Area — Sticky Passthrough: A section whose content fits clips instead of scrolling, so its sticky label passes outward and pins to the panel edge. The next section sets stickyContainment="always" and keeps its label in its own box.
- Scrollable Area — Two-Axis Board: axis="both" gives the content box max-content inline sizing, so a board wider and taller than its panel scrolls on both axes from one viewport.

## Source StyleX compilation

ScrollableAreaOverscrollChaining, ScrollableAreaStickyGroupHeaders, ScrollableAreaStickyPassthrough contain stylex.create and require a StyleX source build pipeline. Precompiled Core CSS alone does not compile these examples. See [Styling](/resources/astryx/docs/styling) before copying them.

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
