Skip to content

ScrollArea

P-08 · Primitives · Primitives

All elements · ScrollArea on the Primitives page

Last checked 2026-10-22 · Awaiting approval · Accessibility tests

Copies the bun run a11y:approve command for ScrollArea.

ScrollArea

P-08WCAG 2.2 AA · Passed #435

A scroll container whose edge shadows appear only when there is more content in that direction. Pure CSS: the shadows are background layers with background-attachment: local, so no scroll listener is needed. Replaces ScrollShadows.

Axis Values
data-axis y (default) · x
data-hide-scrollbar hide the bar, keep the shadows
Vertical and horizontal
  • Row 1
  • Row 2
  • Row 3
  • Row 4
  • Row 5
  • Row 6
  • Row 7
  • Row 8
InvoicesContractsPurchase ordersReceiptsStatementsCorrespondence

Guidance

When to use

  • Scroll a list, pane or panel body inside a fixed-height region with edge shadows that show more content.
  • Scroll a row of chips or filters sideways with data-axis="x".
  • Host a long list that a VirtualScroller windows.
  • Contain scrolling in a pane so the page behind it does not scroll (overscroll-behavior: contain).

When to consider something else

  • When a long result set needs pages and a count, use Pagination instead of an endless scroll. See Pagination.
  • When a toolbar runs out of width, use Overflow to move actions into a menu rather than scrolling them. See Overflow.
  • When the region only needs layout and no scrolling, use Box. See Box.
  • When very long homogeneous lists render slowly, add the VirtualScroller behavior inside the ScrollArea. See Behavioral primitives.

Usability

Do
  • Give the scroll area a bounded height from its parent; min-height: 0 lets it shrink inside flex layouts.
  • Keep the scrollbar visible for vertical lists; use data-hide-scrollbar only for short horizontal rows where shadows signal more.
  • Keep one scroll container per pane.
  • Keep sticky headers inside the same scroll area as their rows.
Don’t
  • Don't nest scroll areas on the same axis.
  • Don't hide the scrollbar on a long list; the shadows show there is more, not how much.
  • Don't scroll the whole page sideways to fit wide content.

Accessibility

Keyboard

ScrollArea keyboard
Keys Action
Tab Moves focus to the scroll area when it has tabindex="0" and no focusable content of its own.
Arrow Down / Arrow Up Scrolls a focused vertical area (browser default).
Arrow Left / Arrow Right Scrolls a focused horizontal area (browser default).
Page Down / Page Up, Home / End Scrolls by a page or to the start or end (browser default).

Roles and names

  • A focusable scroll area uses role="region" with an aria-label, as the specimens do ("Rows", "Document types").
  • When the content inside is a list, grid or listbox, the scroll area does not replace that content's own role.

Focus

  • Add tabindex="0" when the content has no focusable children, so keyboard users can scroll it (2.1.1).
  • The focused scroll area shows the global --qf-focus-ring (2.4.7).
  • When focus moves to an item inside, the browser scrolls it into view; it must not land under a sticky header (2.4.11).

Other requirements

  • Edge shadows are CSS backgrounds with no scroll listener; they carry no meaning to assistive technology.
  • Content must reflow at 320 CSS px without scrolling in two directions, except for data tables and similar content (1.4.10).
  • Hidden scrollbars remove a visual cue; keep them for any list where position matters.

Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.

Accessibility tests

WCAG 2.2 AA · Passed

Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.

ScrollArea test checklist
Area Automated A person checks
General Passed Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme.
Zoom Passed At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping.
Keyboard Passed Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (4 rows)
Screen reader Passed With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (2 items)

Approving. When the checklist passes on the checked run, record it with bun run a11y:approve -- scrollarea --by "Your name" and commit a11y/approvals.json with the rebuilt pages. All test status

Package

Consumers link one stylesheet, css/classic/index.css, which includes every element. The files below are where this element is defined.

ScrollArea package
Source css/classic/primitives/behavior.css
Specimens also use Box · Card · Chip · Icon · List · Table · Text · Toolbar
Sprites sprites/icons.svg
React Not yet available: the React binding has not started.

Latest updates

No recorded changes yet.

All release notes