Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelog App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
ARC UI ARC Radiant Components
v3.2 Docs Components Tokens Synthesizer
Getting StartedFrameworksServer Rendering Design TokensThemingTheme SynthesizerTypographyUtilities All ComponentsAccessibilityBrowser SupportChangelogContributingStats App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip

Scroll Area

Styled scrollable container with custom thin scrollbar styling for Webkit and Firefox, configurable orientation, and optional max-height constraint.

Components Scroll Area
content static
<arc-scroll-area>

Overview

ScrollArea provides a drop-in scrollable container with custom scrollbar styling that integrates seamlessly with ARC UI's design tokens. Instead of the browser's default thick scrollbars, ScrollArea renders slim 6px tracks with rounded thumbs that use the theme's border and surface colors. The thumb darkens subtly on hover, providing visual feedback without drawing excessive attention to chrome. The component supports three orientation modes. The default `"vertical"` orientation enables vertical scrolling while hiding horizontal overflow — the most common pattern for content panels, sidebars, and dropdown menus. Setting `orientation="horizontal"` reverses this for horizontally scrollable galleries or code blocks. The `"both"` option enables scrolling in both directions for large tables or canvas-like content. The `max-height` attribute constrains the container's height, making it ideal for bounding lists, menus, or panels within a fixed space. The inner content renders via the default slot, and the container inherits the parent's border-radius for consistent clipping. ScrollArea is keyboard-accessible with `tabindex="0"` and `role="region"`, allowing keyboard users to scroll with arrow keys when the container is focused.

Guidelines

When to use

  • Set `max-height` when ScrollArea is used inside fixed-height layouts like sidebars, modals, or dropdowns
  • Use `orientation="horizontal"` for image galleries, code blocks, or horizontally scrollable tables
  • Place ScrollArea around content that may exceed the available space rather than letting the entire page scroll
  • Ensure the scroll area has a visible boundary (border or background) so users know the region is scrollable
  • Use `orientation="both"` sparingly — only for truly two-dimensional content like data grids

When not to use

  • Do not nest multiple Scroll Areas — nested scrolling regions create confusing interaction
  • Do not set `max-height` to very small values that hide most content without clear indication
  • Do not use ScrollArea for the main page scroll — it is designed for embedded scrollable regions
  • Do not override the custom scrollbar styles with conflicting global CSS — the component encapsulates them in shadow DOM
  • Avoid using ScrollArea when content fits within the viewport — unnecessary scroll containers add cognitive overhead

Features

  • Custom thin scrollbar styling (6px) for both Webkit and Firefox browsers using design tokens
  • Three orientation modes: `vertical` (default), `horizontal`, and `both` for flexible scroll direction control
  • Optional `max-height` attribute to constrain the scrollable region within a fixed space
  • Smooth scroll behavior via `scroll-behavior: smooth` CSS property
  • Scrollbar thumb hover effect that transitions from border-bright to text-ghost color
  • Keyboard-accessible with `tabindex="0"` and `role="region"` for arrow-key scrolling
  • Inherits parent border-radius for seamless visual clipping
  • Firefox scrollbar support via `scrollbar-width: thin` and `scrollbar-color`

Preview

Line 1: ScrollArea provides styled scrollable containers.

Line 2: Custom thin scrollbars match the design system.

Line 3: Supports vertical, horizontal, and both orientations.

Line 4: Set max-height to constrain the visible area.

Line 5: Keyboard accessible with tabindex and role region.

Line 6: Smooth scroll behavior is enabled by default.

Line 7: Works great in sidebars, modals, and dropdowns.

Line 8: Try scrolling down to see more content below.

Usage

<arc-scroll-area max-height="300px">
  <p>Your scrollable content here...</p>
  <!-- More content that exceeds 300px height -->
</arc-scroll-area>
import { ScrollArea } from '@arclux/arc-ui-react';

export default function Example() {
  return (
    <ScrollArea maxHeight="300px">
      <p>Your scrollable content here...</p>
      {/* More content that exceeds 300px height */}
    </ScrollArea>
  );
}
<script setup>
import { ScrollArea } from '@arclux/arc-ui-vue';
</script>

<template>
  <ScrollArea max-height="300px">
    <p>Your scrollable content here...</p>
    <!-- More content that exceeds 300px height -->
  </ScrollArea>
</template>
<script>
  import { ScrollArea } from '@arclux/arc-ui-svelte';
</script>

<ScrollArea max-height="300px">
  <p>Your scrollable content here...</p>
  <!-- More content that exceeds 300px height -->
</ScrollArea>
import { Component } from '@angular/core';
import { ScrollArea } from '@arclux/arc-ui-angular';

@Component({
  imports: [ScrollArea],
  template: `
    <arc-scroll-area max-height="300px">
      <p>Your scrollable content here...</p>
      <!-- More content that exceeds 300px height -->
    </arc-scroll-area>
  `,
})
export class MyComponent {}
import { ScrollArea } from '@arclux/arc-ui-solid';

export default function Example() {
  return (
    <ScrollArea maxHeight="300px">
      <p>Your scrollable content here...</p>
      {/* More content that exceeds 300px height */}
    </ScrollArea>
  );
}
import { ScrollArea } from '@arclux/arc-ui-preact';

export default function Example() {
  return (
    <ScrollArea maxHeight="300px">
      <p>Your scrollable content here...</p>
      {/* More content that exceeds 300px height */}
    </ScrollArea>
  );
}
<!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-scroll-area — requires scroll-area.css + tokens.css (or arc-ui.css) -->
<div class="arc-scroll-area">
  <div
    class="scroll-area"
    tabindex="0"
    role="region"
    aria-label="Scrollable content"
  >
    ScrollArea
  </div>
</div>
<!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-scroll-area — self-contained, no external CSS needed -->
<style>
  @media (prefers-reduced-motion: reduce) {
    .arc-scroll-area *,
        .arc-scroll-area *::before,
        .arc-scroll-area *::after { animation-duration: 0.01ms !important;
          animation-iteration-count: 1 !important;
          transition-duration: 0.01ms !important; }
  }
  .arc-scroll-area .scroll-area::-webkit-scrollbar-thumb:hover { background: rgb(110, 115, 155); }
</style>
<div class="arc-scroll-area" style="display: block; position: relative">
  <div
    class="scroll-area" style="overflow: hidden; scroll-behavior: smooth; border-radius: var(--radius-full); width: 6px; height: 6px; background: var(--bg-elevated); scrollbar-width: thin; scrollbar-color: var(--border-bright) var(--bg-elevated)"
    tabindex="0"
    role="region"
    aria-label="Scrollable content"
  >
    ScrollArea
  </div>
</div>

API

max-height string ''
CSS max-height value applied to the scrollable container. Use any valid CSS length (e.g. `300px`, `50vh`).
orientation 'vertical' | 'horizontal' | 'both' 'vertical'
Scroll direction. `vertical` shows a vertical scrollbar, `horizontal` shows a horizontal scrollbar, `both` shows both.

See Also