Scroll Area
Styled scrollable container with custom thin scrollbar styling for Webkit and Firefox, configurable orientation, and optional max-height constraint.
<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-heightstring'' - 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.
verticalshows a vertical scrollbar,horizontalshows a horizontal scrollbar,bothshows both.