Skip to content

Scroll Area

LayoutSince 0.9.0
import { ScrollArea } from '@absoluteui/components/scroll-area';
import '@absoluteui/components/scroll-area/style.css';

Using Angular? See Scroll Area for Angular.

Enhances an element whose content can overflow. Scrolling stays native (wheel, touch, trackpad, scrollbar, keyboard); the edges fade where more content exists (a CSS mask, so no elements are added and any background works); and while the content overflows, the element is a named, keyboard-focusable region, so keyboard users can scroll it (WCAG 2.1.1). There are no custom-drawn scrollbars.

  • A bounded panel with long content: release notes, a log, a terms box, a side list.
  • A horizontal strip of cards or chips that scrolls sideways.
  • The whole page (let the document scroll).
  • Large data sets: use Data Table or Data Grid (they virtualize).
  • Content that should simply be shorter.
import { ScrollArea } from '@absoluteui/components/scroll-area';
const notes = document.createElement('div');
for (let i = 1; i <= 30; i++) {
const item = document.createElement('p');
item.textContent = `Release 1.${String(i)}: improvements and fixes.`;
notes.append(item);
}
document.body.append(notes);
ScrollArea.enhance(notes, { label: 'Release notes', maxBlockSize: '12rem' });
import { ScrollArea } from '@absoluteui/components/scroll-area';
import { Badge } from '@absoluteui/components/badge';
const strip = document.createElement('div');
strip.style.display = 'flex';
strip.style.gap = '0.5rem';
for (const label of ['Design', 'Engineering', 'Finance', 'Legal', 'Marketing', 'Operations', 'People', 'Product', 'Sales', 'Support']) {
const host = document.createElement('span');
strip.append(host);
Badge.create(host, { label, variant: 'outline' });
}
document.body.append(strip);
ScrollArea.enhance(strip, { label: 'Departments', orientation: 'horizontal' });
import { ScrollArea } from '@absoluteui/components/scroll-area';
import '@absoluteui/components/scroll-area/style.css';
const terms = document.querySelector<HTMLElement>('#terms');
if (terms) ScrollArea.enhance(terms, { label: 'Terms of service', maxBlockSize: '20rem' });
import { ScrollArea } from '@absoluteui/components/scroll-area';
const log = document.querySelector<HTMLElement>('#activity');
if (log) {
const area = ScrollArea.enhance(log, { label: 'Activity', maxBlockSize: '16rem' });
// After changing content deep inside a child, recompute the edges.
area.refresh();
}
<div class="aui-scroll-area aui-scroll-area--{orientation} aui-scroll-area--shadows"
[role="region" aria-label="Release notes" tabindex="0"] (while overflowing)
[data-aui-scroll-top] [data-aui-scroll-bottom] ...> (edges with hidden content)
... the element's own content ...
</div>
ScrollArea.enhance(element: HTMLElement, options: ScrollAreaOptions): ScrollArea

Global configuration key: scrollArea (see Configuration).

Option Type Default Description
label string Accessible name of the region. Required.
orientation 'vertical' | 'horizontal' | 'both' "vertical" Scroll axis.
maxBlockSize string Maximum block size as a CSS length (sets –aui-scroll-area-max-block-size).
shadows boolean "true" Fade the edges where more content exists. Globally configurable.
Property Type Description
element HTMLElement The enhanced element.
edges ScrollAreaEdges Edges with hidden content ({ top, bottom, left, right }).
overflowing boolean Whether the content overflows (the region is then focusable).
options Readonly<ScrollAreaOptions> Current options.
Method Description
refresh(): void Recompute the edges now.
update(options: Partial<ScrollAreaOptions>): void Merge and apply options.
destroy(): void Remove classes, data attributes, observers, and restore the element’s own attributes.
Area Description
content The element’s own children; they stay in place.

All rules live in the aui.components cascade layer, so application styles override them without specificity battles.

Class Purpose
aui-scroll-area The enhanced element.
aui-scroll-area--vertical | --horizontal | --both Scroll axis.
aui-scroll-area--shadows Edge fades are on.
data-aui-scroll-top | -bottom | -left | -right Present while content is hidden at that edge.

Tokens this stylesheet reads (verified in CI). Override them in a theme or with the Theme Designer.

--aui-color-focus-ring | --aui-focus-ring-offset | --aui-focus-ring-width | --aui-space-6

type ScrollAreaOrientation = 'vertical' | 'horizontal' | 'both';
interface ScrollAreaConfig { shadows: boolean }
interface ScrollAreaOptions extends Partial<ScrollAreaConfig> {
label: string;
orientation?: ScrollAreaOrientation;
maxBlockSize?: string;
}
interface ScrollAreaEdges { readonly top: boolean; readonly bottom: boolean; readonly left: boolean; readonly right: boolean }

Pattern: Scrollable region (WCAG 2.1.1): a scrollable element that holds no focusable content must itself be focusable and named; it is a region with aria-label while it overflows.

Key Context Action
Tab Page Moves to the region while its content overflows.
Arrow keys / Page Up / Page Down / Home / End / Space Focused region Scroll natively.
Element Role
element region while overflowing when it is a generic div or span; otherwise its own role (a list stays a list)
Attribute Element Value
aria-label element the label option, while overflowing
tabindex element 0 while overflowing (an existing tabindex is kept)

Focusable only while there is something to scroll; the focus ring is drawn with the fades off.

Criterion Level Note
1.3.1 Info and Relationships A
2.1.1 Keyboard A
2.4.7 Focus Visible AA
4.1.2 Name, Role, Value A

Automated test results: Accessibility and compliance.

  • The fades are a visual hint only; screen-reader users reach all content in reading order.
  • No custom scrollbars: the platform scrollbar, including its high-contrast and accessibility settings, is kept.
  • Manual screen-reader verification (NVDA, JAWS, VoiceOver) is pending.

Overflowing or not; scrolled to the start, the middle, or the end; vertical, horizontal, or both; fades on or off.

From Trigger To
not overflowing content or size change overflowing: region role, label, and tab stop added
overflowing scroll edge attributes follow the position (at most once per frame)
overflowing content shrinks not overflowing: the element’s own attributes restored
  • The fades are a visual hint; screen-reader users reach all content in reading order.
  • The platform scrollbar, with its accessibility settings, is kept.
  • The fades turn off while the region has keyboard focus, so the focus ring is never clipped.
  • The e2e axe run covers three themes; manual screen-reader verification is pending.

Takes the size its layout gives it; maxBlockSize caps the height.

Horizontal fades follow the scroll position in right-to-left layouts, where content starts at the right edge.

The fades are a mask, so they work on any background color. They are off in forced-colors mode.

configureAbsoluteUI({ components: { scrollArea: { shadows: false } } });

The instance shadows overrides configuration; configuration changes re-render existing scroll areas.

maxBlockSize accepts only plain CSS lengths and calc(), min(), max(), or clamp() expressions, and is set through the CSSOM.

No persistence, network access, or telemetry.

Edge state updates at most once per animation frame while scrolling. Resize observers watch the element and its direct children; a mutation observer re-attaches them when children change.

Any amount of content that the browser can render; use the data components for large data sets.

  • A region that stops overflowing is no longer focusable; if it had focus, focus stays on it until the user moves on.
  • Size changes deeper than the direct children are noticed when a direct child resizes; call refresh() after other changes.
Code Category Cause
SCROLL_AREA_HOST configuration The target is not an element.
SCROLL_AREA_OPTIONS configuration Blank label, an unknown orientation, or a maxBlockSize that is not a plain CSS length.
CFG_INVALID_VALUE / CFG_UNKNOWN_OPTION configuration Invalid or unknown configuration.

Invalid options throw before the element is modified.

  • The fades also fade content at the edges; avoid placing controls right at the edge.
  • Manual screen-reader verification is pending.
  • Custom scrollbars.
  • Virtualized content.