Scroll Area
Tags
<div class="scroll-area" tabindex="0" style="height: 12rem; width: 21rem; border: 1px solid var(--border); border-radius: 0.5rem; padding: 1rem"> <h4 style="margin: 0 0 0.75rem; font-size: 0.875rem; font-weight: 500">Tags</h4> <div style="display: grid; gap: 0.5rem; font-size: 0.875rem"> <div>v1.2.0-beta.50</div> <hr class="separator" /> <div>v1.2.0-beta.49</div> <hr class="separator" /> <div>v1.2.0-beta.48</div> <hr class="separator" /> <div>v1.2.0-beta.47</div> <hr class="separator" /> <div>v1.2.0-beta.46</div> <hr class="separator" /> <div>v1.2.0-beta.45</div> <hr class="separator" /> <div>v1.2.0-beta.44</div> <hr class="separator" /> <div>v1.2.0-beta.43</div> </div></div><div class="scroll-area" tabindex="0" style="height: 12rem">…</div>The element scrolls itself — this only restyles the bar. Give it a height (or a max-height), and
tabindex="0" so it can be scrolled from the keyboard.
| Attribute | Meaning |
|---|---|
data-orientation="horizontal" | Scrolls sideways only |
data-orientation="vertical" | Scrolls down only |
data-bars="hidden" | No visible bar, same scrolling |
Horizontal
Section titled “Horizontal”<div class="scroll-area" data-orientation="horizontal" tabindex="0" style="width: 26rem; padding-bottom: 0.75rem"> <div style="display: flex; gap: 1rem"> <figure style="margin: 0; flex-shrink: 0"> <div class="skeleton" style="height: 8rem; width: 10rem; border-radius: 0.5rem"></div> <figcaption style="padding-top: 0.5rem; font-size: 0.75rem; color: var(--muted-foreground)"> Photo by Ada </figcaption> </figure> <figure style="margin: 0; flex-shrink: 0"> <div class="skeleton" style="height: 8rem; width: 10rem; border-radius: 0.5rem"></div> <figcaption style="padding-top: 0.5rem; font-size: 0.75rem; color: var(--muted-foreground)"> Photo by Grace </figcaption> </figure> <figure style="margin: 0; flex-shrink: 0"> <div class="skeleton" style="height: 8rem; width: 10rem; border-radius: 0.5rem"></div> <figcaption style="padding-top: 0.5rem; font-size: 0.75rem; color: var(--muted-foreground)"> Photo by Alan </figcaption> </figure> </div></div>Without a visible bar
Section titled “Without a visible bar”The bar is gone, the scrolling is not.
Wheel, trackpad, touch and the keyboard all still work.
Only reach for this where an edge already says there is more.
Otherwise people cannot tell the content continues.
<div class="scroll-area" data-bars="hidden" tabindex="0" style="height: 8rem; width: 18rem; border: 1px solid var(--border); border-radius: 0.5rem; padding: 1rem; font-size: 0.875rem"> <p style="margin: 0 0 0.75rem">The bar is gone, the scrolling is not.</p> <p style="margin: 0 0 0.75rem">Wheel, trackpad, touch and the keyboard all still work.</p> <p style="margin: 0 0 0.75rem">Only reach for this where an edge already says there is more.</p> <p style="margin: 0">Otherwise people cannot tell the content continues.</p></div>Why there is no JavaScript here
Section titled “Why there is no JavaScript here”Radix draws its own scrollbars, so they look identical in every browser. That costs the native
scroll: momentum on a trackpad, overscroll, the platform’s own keyboard handling, and correct
behaviour when the page is zoomed. scrollbar-width and scrollbar-color are now supported
everywhere, and WebKit takes ::-webkit-scrollbar — enough to get the same look and keep the
scroller the browser gave you.
Set dir="rtl" on the page or on any subtree — the bar moves to the left edge, which the browser
does on its own. See the button page for a live example.
Accessibility
Section titled “Accessibility”- A scrollable box must be focusable.
tabindex="0"is what lets a keyboard user reach it and scroll it; without it, content inside is unreachable unless it holds its own controls. - Give it a name when it is focusable —
aria-labeloraria-labelledby— so a screen reader says what the region is rather than announcing a bare group. - Do not turn off overflow to hide the bar.
data-bars="hidden"keeps the element scrollable;overflow: hiddenwould trap the content. - The bar respects the theme, drawn from
--border, so it stays visible in dark mode instead of inheriting whatever the OS decided.