Scroll Area
Navigation & layoutBrick 0.1.2

Scroll Area

Scroll Area constrains native browser scrolling to explicit axes while keeping content, input, momentum, and platform scrollbar behavior native. It adopts Atom's Root/Viewport behavior and adds finished gutter, visibility, focus, and semantic-color styling.

Live example

Built from the published package

Interactive
Published Brick 0.1.0
Updated component docs
Verified theme tokens
Ran browser checks
Prepared release notes
Choose with confidence

Know when Scroll Area is the right part

Use it when

Use it when a region is deliberately size-constrained and its content must remain available by scrolling: navigation rails, activity panels, horizontal rails, and bounded work areas.

Choose another path when

Do not use it for normal document scrolling, responsive reflow, accidental overflow, clipping, overlay boundaries, or code samples before Code Block owns that behavior. Fix unintended overflow instead of hiding it.

Installation and imports

tsx
import { ScrollArea } from "@flowstack-ui/brick";
// or
import { ScrollArea } from "@flowstack-ui/brick/scroll-area";
import "@flowstack-ui/brick/styles.css";

The complete stylesheet above is the recommended default. For a measured route-aware build, replace it with the shared foundation and this component's stylesheet:

tsx
import "@flowstack-ui/brick/styles/core.css"; // once at the application root
import "@flowstack-ui/brick/styles/scroll-area.css";

Add the modular stylesheet for every other Brick component the route renders. Do not combine modular styles with styles.css or tokens.css.

Quick start

tsx
<ScrollArea.Root style={{ blockSize: 240 }}>
  <ScrollArea.Viewport aria-label="Recent activity" focusable>
    <ActivityList />
  </ScrollArea.Viewport>
</ScrollArea.Root>

Visual recipes and states

Orientation changes only enabled physical axes. Gutter changes only reserved scrollbar space. Visibility changes only the native scrollbar request and authored color visibility; it never disables scrolling. The component has no tone, size, radius, disabled, loading, validation, or motion recipe.

Examples

Horizontal rail

tsx
<ScrollArea.Root orientation="horizontal" scrollbarVisibility="interaction">
  <ScrollArea.Viewport aria-label="Project filters">
    <HStack>{filters}</HStack>
  </ScrollArea.Viewport>
</ScrollArea.Root>

Interactive descendants without an extra stop

tsx
<ScrollArea.Root>
  <ScrollArea.Viewport>{projectLinks}</ScrollArea.Viewport>
</ScrollArea.Root>
Public contract

API

Start with the public parts and root options below. Components with multiple parts separate each area into its own named subsection.

Part or propValuesDefault
orientationvertical, horizontal, bothvertical
scrollbarGutterauto, stableauto
scrollbarVisibilityauto, always, interactionauto
Viewport.focusablebooleanfalse
Root and Viewport compositionrender, asChildnative div

auto preserves native scrollbar policy. always requests scrollbars even without overflow, although operating systems may use overlay scrollbars. interaction keeps scrolling available and reveals authored scrollbar color on hover or focus-within; touch and forced-colors environments remain native.

Public exports are ScrollArea, ScrollAreaRoot, ScrollAreaViewport, ScrollAreaOrientation, ScrollAreaScrollbarGutter, ScrollAreaScrollbarVisibility, ScrollAreaRootElement, ScrollAreaRootProps, ScrollAreaViewportElement, and ScrollAreaViewportProps.

Shared responsibility

Accessibility

Scroll Area adds no role or tab stop by default. If plain content needs keyboard scrolling, set focusable and provide a specific accessible name. When focusable descendants already make content reachable, avoid an extra viewport stop. Never use role="application".

Responsive behavior

Scroll Area fills the consumer-provided box and does not add breakpoints. Native wheel, touch, keyboard, RTL, writing-mode, nested-scroll handoff, and reduced-motion behavior remain intact. Axis values are physical because native overflow axes are physical.

Stable visual contract

Styling and tokens

Customization

tsx
<ScrollArea.Root
  style={{
    "--brick-scroll-area-scrollbar-thumb": "rebeccapurple",
    "--brick-scroll-area-scrollbar-track": "lavender",
  }}
>
  <ScrollArea.Viewport>{content}</ScrollArea.Viewport>
</ScrollArea.Root>

Customize only scrollbar colors through these public variables. Application layout continues to own the viewport constraint.

Tokens and CSS hooks

Hooks are .brick-scroll-area, .brick-scroll-area-viewport, Atom data-slot and data-orientation, plus data-scrollbar-gutter and data-scrollbar-visibility.

Public variables:

  • --brick-scroll-area-scrollbar-thumb
  • --brick-scroll-area-scrollbar-track

Advanced reference

Open these details only when you need to inspect DOM ownership, native forwarding, or lower-level composition.

Maintainer resources

Tests, playground evidence, source notes, and release history remain available without crowding the plug-and-play guide.