Add this component

npx zentauri-ui add scroll-area

Accessibility notes

Keyboard accessible by default with semantic markup, visible focus treatment, and tokenized states. Add descriptive labels for icon-only or decorative usage.

Dependency notes

Check Installation for shared peers. This component keeps styling in Tailwind classes and the --zui-* token contract.

Layout

Themeable scroll containers for dense interfaces

ScrollArea wraps overflowing content in a consistent, token-driven container. Use it for activity feeds, command panels, metric rails, compact tables, and any section where browser default scrollbars feel too heavy or inconsistent.

Step 01

Webhook received from billing service

Step 02

Customer profile merged with workspace identity

Step 03

Invoice draft generated for approval

Step 04

Payment method validated through risk checks

Step 05

Receipt queued for transactional email

Step 06

Usage counters synchronized to analytics

Step 07

Admin notification posted to the audit stream

Step 08

Workspace limits recalculated for the next cycle

QueuedBuildingPreviewChecksPromote

Examples

ScrollArea standardizes overflow panels, horizontal rails, hidden scrollbars, and hover-revealed thumbs without adding a JavaScript positioning dependency.


1.Keyboard focus remains visible when the scroll container is named.
2.Scrollbar colors are driven by component CSS variables.
3.Horizontal layouts can keep chip rails and tab bars compact.
4.Hover scrollbars reduce visual weight in dense dashboards.
5.Hidden scrollbars preserve scroll behavior for custom chrome.
6.Shadow treatment adds depth for nested information panels.

API latency

128 ms

Queue depth

42 jobs

Cache hit rate

94.8%

Deploy window

7 min

Error budget

99.93%

SLO drift

0.04%

API Security

100%

Scroll Area variants playground

Pick an appearance, size, orientation, scrollbar, and shadow to preview the scroll area live. Toggle Show output / Show code and the snippet updates to match the selected variant.


01Design token sync completed
02Preview route generated
03SEO document attached
04Package export verified
05Regression suite queued
06Release note drafted
07CLI registry updated
08Homepage health refreshed

All appearances

Every shipped appearance token at a glance. Click any swatch to load it into the playground above.

Scroll Area API

Generated from the package prop types and variant definitions.

ScrollArea

ScrollAreaProps

Variants

PropTypeDefault
appearance
amberaquabluecrimsoncyandefaultelectricemeraldforestglassgreenlavender+18
default
orientation
bothhorizontalvertical
vertical
scrollbar
alwaysautohiddenhover
auto
shadow
falsetrue
none
size
lgmdsm
md

Behavior

PropTypeDefault
viewportClassNamestring | undefinednone
Inherited HTML props
PropTypeDefault
childrenReactNodenone
classNamestring | undefinednone
idstring | undefinednone
onClickMouseEventHandler<HTMLDivElement> | undefinednone
styleCSSProperties | undefinednone
titlestring | undefinednone

ScrollAreaVariant

ScrollAreaVariantProps

Behavior

PropTypeDefault
appearance'default' | 'outline' | 'blue' | 'cyan' | 'green' | 'lime' | 'mint' | 'ocean' | 'sapphire' | 'lavender' | 'ruby' | 'red' | 'slate' | 'zinc' | 'stone' | 'royal' | 'electric' | 'forest' | 'sunset' | 'magenta' | 'crimson' | 'aqua' | 'plum' | 'sky' | 'rose' | 'emerald' | 'violet' | 'glass' | 'muted' | 'amber' | null | undefinednone
orientation'both' | 'horizontal' | 'vertical' | null | undefinednone
scrollbar'hidden' | 'auto' | 'always' | 'hover' | null | undefinednone
shadowboolean | null | undefinednone
size'md' | 'sm' | 'lg' | null | undefinednone
CSS variable overrides

ScrollArea CSS variables

Override these ScrollArea variables on :root, a theme selector, or a component wrapper.

150 variables

Pattern: --zui-<component>-<slot?>-<variant?>-<property>-<state?>-dark?

:root {
  --zui-scroll-area-thumb: #94a3b8;
  --zui-scroll-area-track: transparent;
  --zui-scroll-area-ring-focus: oklch(54.6% 0.245 262.881 / 0.28);
  --zui-scroll-area-ring-offset-focus: #ffffff;
  --zui-scroll-area-size: 0.625rem;
  --zui-scroll-area-thumb-border: transparent;
  --zui-scroll-area-outline-border: #cbd5e1;
  --zui-scroll-area-glass-border: #ffffff80;
  --zui-scroll-area-glass-bg: #ffffff99;
  --zui-scroll-area-sky-border: oklch(62.3% 0.214 259.815 / 0.35);
  --zui-scroll-area-emerald-border: oklch(59.6% 0.145 163.225 / 0.35);
  --zui-scroll-area-rose-border: oklch(58.6% 0.253 17.585 / 0.3);
  --zui-scroll-area-amber-border: oklch(76.9% 0.188 70.08 / 0.35);
  --zui-scroll-area-violet-border: oklch(60.6% 0.25 292.717 / 0.35);
  --zui-scroll-area-blue-border: #2563eb66;
  --zui-scroll-area-blue-thumb: #2563eb;
  --zui-scroll-area-blue-track: #2563eb14;
  --zui-scroll-area-cyan-border: #0891b266;
  --zui-scroll-area-cyan-thumb: #0891b2;
  --zui-scroll-area-cyan-track: #0891b214;
  --zui-scroll-area-green-border: #16a34a66;
  --zui-scroll-area-green-thumb: #16a34a;
  --zui-scroll-area-green-track: #16a34a14;
  --zui-scroll-area-lime-border: #65a30d66;
  --zui-scroll-area-lime-thumb: #65a30d;
  --zui-scroll-area-lime-track: #65a30d14;
  --zui-scroll-area-mint-border: #10b98166;
  --zui-scroll-area-mint-thumb: #10b981;
  --zui-scroll-area-mint-track: #10b98114;
  --zui-scroll-area-ocean-border: #0284c766;
  --zui-scroll-area-ocean-thumb: #0284c7;
  --zui-scroll-area-ocean-track: #0284c714;
  --zui-scroll-area-sapphire-border: #1d4ed866;
  --zui-scroll-area-sapphire-thumb: #1d4ed8;
  --zui-scroll-area-sapphire-track: #1d4ed814;
  --zui-scroll-area-lavender-border: #8b5cf666;
  --zui-scroll-area-lavender-thumb: #8b5cf6;
  --zui-scroll-area-lavender-track: #8b5cf614;
  --zui-scroll-area-ruby-border: #be123c66;
  --zui-scroll-area-ruby-thumb: #be123c;
  --zui-scroll-area-ruby-track: #be123c14;
  --zui-scroll-area-red-border: #dc262666;
  --zui-scroll-area-red-thumb: #dc2626;
  --zui-scroll-area-red-track: #dc262614;
  --zui-scroll-area-slate-border: #47556966;
  --zui-scroll-area-slate-thumb: #475569;
  --zui-scroll-area-slate-track: #47556914;
  --zui-scroll-area-zinc-border: #52525b66;
  --zui-scroll-area-zinc-thumb: #52525b;
  --zui-scroll-area-zinc-track: #52525b14;
  --zui-scroll-area-stone-border: #57534e66;
  --zui-scroll-area-stone-thumb: #57534e;
  --zui-scroll-area-stone-track: #57534e14;
  --zui-scroll-area-royal-border: #4338ca66;
  --zui-scroll-area-royal-thumb: #4338ca;
  --zui-scroll-area-royal-track: #4338ca14;
  --zui-scroll-area-electric-border: #0ea5e966;
  --zui-scroll-area-electric-thumb: #0ea5e9;
  --zui-scroll-area-electric-track: #0ea5e914;
  --zui-scroll-area-forest-border: #16653466;
  --zui-scroll-area-forest-thumb: #166534;
  --zui-scroll-area-forest-track: #16653414;
  --zui-scroll-area-sunset-border: #ea580c66;
  --zui-scroll-area-sunset-thumb: #ea580c;
  --zui-scroll-area-sunset-track: #ea580c14;
  --zui-scroll-area-magenta-border: #c026d366;
  --zui-scroll-area-magenta-thumb: #c026d3;
  --zui-scroll-area-magenta-track: #c026d314;
  --zui-scroll-area-crimson-border: #b91c1c66;
  --zui-scroll-area-crimson-thumb: #b91c1c;
  --zui-scroll-area-crimson-track: #b91c1c14;
  --zui-scroll-area-aqua-border: #0f766e66;
  --zui-scroll-area-aqua-thumb: #0f766e;
  --zui-scroll-area-aqua-track: #0f766e14;
  --zui-scroll-area-plum-border: #7e22ce66;
  --zui-scroll-area-plum-thumb: #7e22ce;
  --zui-scroll-area-plum-track: #7e22ce14;
}

/* Dark theme variables follow the same names with -dark appended. */
.dark {
  --zui-scroll-area-ring-focus-dark: oklch(70.7% 0.165 254.624 / 0.28);
  --zui-scroll-area-ring-offset-focus-dark: oklch(12.9% 0.042 264.695);
}

What it does

ScrollArea gives overflowing content a consistent scrollbar treatment across product surfaces.

It supports vertical, horizontal, and two-axis scrolling, plus auto, hover, always, and hidden scrollbar visibility modes.

Composition and API

Use ScrollArea as a single wrapper around content. Pass className for the scroll container size and padding, viewportClassName for inner layout, and variants such as appearance, size, orientation, scrollbar, and shadow.

Common use cases

Use ScrollArea to standardize scrollbar appearance across different browsers and platforms. It is ideal for sidebar navigation, dropdown menus, chat feeds, log viewers, and horizontal card carousels where native scrollbars would look inconsistent or bulky.

Accessibility

Use aria-label when the scrollable region has standalone meaning. The component maps named regions to role=region and tabIndex=0 unless you provide your own role or tabIndex.

Next.js integration notes

ScrollArea ships as a client-safe package entry because it owns interactive focus attributes, but it has no effects or runtime layout work. You can render it inside App Router preview pages while keeping SEO content server-rendered.

FAQ

Does ScrollArea require JavaScript for positioning?

No. ScrollArea uses CSS overflow, CSS custom properties, and browser scrollbar styling, so it does not need a layout or positioning dependency.

Can ScrollArea scroll horizontally?

Yes. Set orientation to horizontal and give the viewport content a minimum width, such as min-w-max or a fixed grid width.

How do I make a ScrollArea accessible?

Provide aria-label or role and label content when the scroll region is meaningful on its own. Named regions become keyboard-focusable by default so users can scroll them with the keyboard.