Scroll area
Gives long content its own scrolling box.
Examples
Orientation
verticaldefault
horizontal
both
States
rest
hovering
focus-visible
nothing to scroll
Usage
When to use it
- Use
- A list inside a panel or popover with a fixed height, such as a merchant picker.
- Use
- A code block or wide strip of chips that scrolls sideways.
- Use
- A panel that must cap its height.
- Not for
- The page itself. Let the browser scroll it.
- Not for
- A long list inside a Select, which caps and scrolls its own popup. Use Select.
- Not for
- A table wider than its column; Table scrolls in its own wrapper. Use Table.
Rules
7 rules
- Must
- Give a vertical scroll area a height or max height. Because without one the area grows with its rows and never scrolls.
- Should
- Let a row be cut by the edge; the thumb is hidden at rest, so a cut item says there is more.
- Should
- Pass aria-label such as "Merchants"; the viewport is a focus stop and needs a name.
- Never
- Hide the scrollbar with CSS; use ScrollArea, which keeps native scrolling and a thumb. Because a hidden bar never shows, even on hover, so a mouse user cannot tell the list scrolls.
- Should
- Prefer vertical; use orientation="both" only for tables and frames.
- Must
- Keep the viewport focusable so arrow keys scroll it; never tabIndex -1. Because a keyboard user cannot reach an unfocusable region, so rows below the fold are lost.
- Should
- Set overscroll-contain in a popover or dialog so scrolling does not chain to the page.
Accessibility
5 checks
- The viewport is a Tab stop that scrolls with arrow keys, Page and Home or End.
- Focus shows a 2px olive ring inside the edge.
- Name the region with aria-label.
- Native scrolling and momentum are kept; the 10px thumb is not for finger dragging.
- The thumb is a background fill and may vanish in forced colors; scrolling still works.
Edge cases
6 edge cases
- Right to left
- The vertical bar moves to the left edge, following the writing direction. The specimen keeps the thumb shown.
- Long unbroken string
- It overflows sideways and scrolls only if orientation includes horizontal.
- Short content
- No thumb; the area keeps the height you gave it.
- Thousands of items
- Use a virtual list; 500 nodes scroll natively.
- More loads on scroll
- Add your own sentinel; the area has no loading part.
- Reduced motion
- The thumb appears and goes at once.
API
2 props
orientation'vertical' | 'horizontal' | 'both'default'vertical'classNamestring
Tokens
4 tokens
--line-strong- #cfcdc6
--control- #85827a
--scrollbar-thumb- var(--line-strong)
--dur-fast- 140ms