Skip to content

ComponentsLayout

Scroll Area

A scroll container with thin, themed scrollbars and optional fading edges. Native scrolling (wheel, touch, keyboard and scroll snapping all work as usual), styled with CSS only, vertically, horizontally or both, with always-visible, hover-only or hidden scrollbars.

Source

Changelog

  • v4.12.0Oct 2

    Bulk edit for invoices and a new CSV importer.

  • v4.11.3Sep 26

    Fixed rounding in multi-currency totals.

  • v4.11.2Sep 22

    Faster search on workspaces with 10k+ documents.

  • v4.11.0Sep 15

    Approval rules for expenses over a set amount.

  • v4.10.4Sep 8

    Webhook retries now back off exponentially.

  • v4.10.0Sep 1

    Dark mode for the mobile apps.

  • v4.9.2Aug 25

    Audit log export to S3 and GCS.

  • v4.9.0Aug 18

    Custom fields on vendors and customers.

  • v4.8.1Aug 11

    SAML just-in-time provisioning.

  • v4.8.0Aug 4

    Recurring invoices with proration.

Installation

pnpm dlx shadcn@latest add @desyne/scroll-area

The CLI installs dependencies and any other components this one uses.

Usage

tsx
import { ScrollArea } from "@/components/ui/scroll-area";
tsx
<ScrollArea className="h-64" aria-label="Changelog">
  {/* long content */}
</ScrollArea>

Give the scroll area a fixed height (or width for horizontal scrolling), or put it in a flex or grid parent that limits its size.

When to use

  • Scroll Area: a region inside a page that scrolls on its own, such as a list in a card, a row of cards, or a wide table, where the default scrollbar looks heavy.
  • Let the page scroll when the content is the main thing on the page. Nested scrolling regions are harder to use, especially on touch devices.
  • Carousel: horizontally scrolling slides with previous and next buttons.

Anatomy

tsx
<ScrollArea>   {/* the scroll container, tabIndex=0 */}
  {children}
</ScrollArea>
PartRendersNotes
ScrollArea<div>overflow: auto on the chosen axes, a thin scrollbar via scrollbar-width and scrollbar-color (with ::-webkit-scrollbar styles for older WebKit), and overscroll-behavior: contain. Focusable, with a focus ring.

There's no custom scrollbar element: the browser draws the scrollbar, so platform behaviors like overlay scrollbars on macOS and momentum scrolling are kept.

Examples

Horizontal

orientation="horizontal" scrolls sideways. Give the content w-max (or a fixed width) so it doesn't wrap.

  • Linen bedding

    24 products

  • Stoneware

    41 products

  • Wool throws

    12 products

  • Oak furniture

    18 products

  • Ceramic lamps

    9 products

  • Rugs

    33 products

  • Glassware

    27 products

Fade edges

fade masks the edges that have more content beyond them, and updates as you scroll and when the content resizes. Pass a number for the fade size in px (default 24). The mask covers everything on the element, borders included, so put borders and backgrounds on a wrapper.

1. Acceptance

By creating an account you agree to these terms and to our privacy policy. If you use the service on behalf of a company, you confirm you can bind it to these terms.

2. Your account

Keep your password secure and tell us right away about any unauthorized use. You're responsible for activity under your account.

3. Billing

Paid plans renew automatically each month or year. You can cancel at any time; access continues until the end of the current period.

4. Your content

You own what you upload. You give us permission to host and process it only to run the service for you.

5. Acceptable use

Don't use the service to break the law, send spam, or interfere with other customers. We may suspend accounts that do.

6. Termination

You can close your account from settings. We'll keep an export of your data available for 30 days.

Both directions

orientation="both" scrolls on both axes. Sticky headers and columns work as usual, since the scroll area is the scroll container.

Region ($k)JanFebMarAprMayJunJulAugSepOctNovDec
North America409662118841401067212894150116
South America77439965121871431097513197153
Western Europe1148046102681249014611278134100
Eastern Europe611178349105711279314911581137
Middle East98641208652108741309615211884
Africa451016712389551117713399155121
South Asia824810470126925811480136102158
East Asia119855110773129956111783139105
Oceania66122885411076132986412086142
Caribbean103691259157113791351016712389
Central America501067212894601168213810470126
Nordics87531097513197631198514110773

Scrollbar visibility

scrollbar="thin" (default) is always visible, hover shows it only while the pointer is over the area or it has keyboard focus, and hidden removes it while keeping wheel, touch and keyboard scrolling.

scrollbar="thin"
AllDesignEngineeringMarketingSalesSupportFinanceLegalPeopleOperationsSecurityData
scrollbar="hover"
AllDesignEngineeringMarketingSalesSupportFinanceLegalPeopleOperationsSecurityData
scrollbar="hidden"
AllDesignEngineeringMarketingSalesSupportFinanceLegalPeopleOperationsSecurityData

Accessibility

  • The scroll area has tabIndex={0} by default, so keyboard users can focus it and scroll with the arrow keys, Page Up/Down, Home and End. Pass tabIndex={-1} if the content is already fully reachable by tabbing through focusable children.
  • Because it's focusable, give it a name with aria-label or aria-labelledby, and consider role="region" for large, landmark-like areas.
  • With scrollbar="hidden", nothing shows that the area scrolls. Use it only when the content makes it obvious (a cut-off row of chips, a fade edge).
  • Fades are visual only and respect the content beneath them; they don't block pointer events.

Styling

Data attributes

AttributeOnValues
data-slot="scroll-area"RootAlways
data-orientationRootvertical · horizontal · both

Scrollbar color

The thumb color is the --scroll-thumb variable (35% of --muted-foreground). Override it on the scroll area or any ancestor:

tsx
<ScrollArea className="[--scroll-thumb:var(--brand)]">…</ScrollArea>

scrollAreaVariants

The tailwind-variants function behind ScrollArea. Apply it to any element to get the same scrollbars without the fade logic, for example a <pre> or a <table> wrapper.

API Reference

Prop

Type

Also accepts every prop of <div>, including ref and onScroll.

  • Carousel: slides with navigation.
  • Table: wide tables inside a scroll area.
  • Card: a frame around a scrolling list.