Scroll Area

Augments native scroll functionality for custom, cross-browser styling.

Requires JavaScript

Tags

v1.2.0-beta.1
v1.2.0-beta.0
v1.1.2
v1.1.1
v1.1.0
v1.0.0
v0.9.0
v0.8.0
v0.7.0
v0.6.0
v0.5.0
v0.4.0
v0.3.0
v0.2.0
v0.1.0
scroll-area/default
<%= render Shadcn::ScrollArea.new(class_name: "h-64 w-full max-w-md rounded-md border") do %>
  <pre class="p-4 text-sm"><code>import { ScrollArea } from "@/components/ui/scroll-area"

export function ScrollAreaDemo() {
  return (
    &lt;ScrollArea className="h-72 w-48 rounded-md border"&gt;
      &lt;div className="p-4"&gt;
        &lt;h4 className="mb-4 text-sm font-medium leading-none"&gt;
          Tags
        &lt;/h4&gt;
        {Array.from({ length: 50 }).map((_, i) =&gt; (
          &lt;div key={i} className="text-sm"&gt;
            v1.2.0-beta.{i}
          &lt;/div&gt;
        ))}
      &lt;/div&gt;
    &lt;/ScrollArea&gt;
  )
}</code></pre>
<% end %>

Installation

Add the component to your project:

rails generate shadcn:add scroll_area

Usage

<%= render Shadcn::ScrollArea.new(class_name: "h-64 w-full max-w-md rounded-md border") do %>
  <pre class="p-4 text-sm"><code>import { ScrollArea } from "@/components/ui/scroll-area"

export function ScrollAreaDemo() {
  return (
    &lt;ScrollArea className="h-72 w-48 rounded-md border"&gt;
      &lt;div className="p-4"&gt;
        &lt;h4 className="mb-4 text-sm font-medium leading-none"&gt;
          Tags
        &lt;/h4&gt;
        {Array.from({ length: 50 }).map((_, i) =&gt; (
          &lt;div key={i} className="text-sm"&gt;
            v1.2.0-beta.{i}
          &lt;/div&gt;
        ))}
      &lt;/div&gt;
    &lt;/ScrollArea&gt;
  )
}</code></pre>
<% end %>

Examples

Vertical Scroll

The default orientation for scrollable content.

Items

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
Item 13
Item 14
Item 15
Item 16
Item 17
Item 18
Item 19
Item 20
Item 21
Item 22
Item 23
Item 24
Item 25
Item 26
Item 27
Item 28
Item 29
Item 30
<%= render Shadcn::ScrollAreaComponent.new(orientation: :vertical, class_name: "h-72 w-48 rounded-md border") do %>
  <div class="p-4">
    <h4 class="mb-4 text-sm font-medium leading-none">Items</h4>
    <% (1..30).each_with_index do |i, index| %>
      <div class="text-sm">Item <%= i %></div>
      <%= content_tag(:div, "", class: "my-2 h-px bg-border") unless index == 29 %>
    <% end %>
  </div>
<% end %>

Horizontal Scroll

Use for horizontally scrolling content like image galleries.

<%= render Shadcn::ScrollAreaComponent.new(orientation: :horizontal, class_name: "w-96 whitespace-nowrap rounded-md border") do %>
  <div class="flex w-max space-x-4 p-4">
    <% image_urls = (1..10).map { |i| "https://picsum.photos/300/200?random=#{i}" } %>
    <% image_urls.each do |url| %>
      <%= image_tag url, class: "h-[200px] w-[300px] rounded-md object-cover" %>
    <% end %>
  </div>
<% end %>

Tags List

Combine with other components like badges for rich content.

Popular Tags

Ruby Rails ViewComponent Stimulus Hotwire Turbo React Next.js Vue Angular Svelte TypeScript JavaScript Python Django Flask
<%= render Shadcn::ScrollAreaComponent.new(class_name: "h-48 w-full rounded-md border") do %>
  <div class="p-4">
    <h4 class="mb-4 text-sm font-medium leading-none">Popular Tags</h4>
    <div class="flex flex-wrap gap-2">
      <% tags = ["Ruby", "Rails", "ViewComponent", "Stimulus", "Hotwire", "Turbo", "React", "Next.js", "Vue", "Angular", "Svelte", "TypeScript", "JavaScript", "Python", "Django", "Flask"] %>
      <% tags.each do |tag| %>
        <%= render Shadcn::BadgeComponent.new(variant: :secondary) { tag } %>
      <% end %>
    </div>
  </div>
<% end %>

Fixed Height Container

Ideal for containing long content in a fixed-height area with custom scrollbars.

Terms and Conditions

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

<%= render Shadcn::ScrollAreaComponent.new(class_name: "h-96 w-full rounded-md border") do %>
  <div class="p-4 space-y-4">
    <h4 class="text-lg font-semibold">Terms and Conditions</h4>
    <% 5.times do %>
      <p class="text-sm text-muted-foreground">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
        Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
        Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
      </p>
    <% end %>
  </div>
<% end %>

Vertical

Lorem Ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.

Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.

scroll-area/vertical
<%= render Shadcn::ScrollArea.new(class_name: "h-64 w-full max-w-md rounded-md border") do %>
  <pre class="p-4 text-sm"><code>import { ScrollArea } from "@/components/ui/scroll-area"

export function ScrollAreaDemo() {
  return (
    &lt;ScrollArea className="h-72 w-48 rounded-md border"&gt;
      &lt;div className="p-4"&gt;
        &lt;h4 className="mb-4 text-sm font-medium leading-none"&gt;
          Tags
        &lt;/h4&gt;
        {Array.from({ length: 50 }).map((_, i) =&gt; (
          &lt;div key={i} className="text-sm"&gt;
            v1.2.0-beta.{i}
          &lt;/div&gt;
        ))}
      &lt;/div&gt;
    &lt;/ScrollArea&gt;
  )
}</code></pre>
<% end %>

Horizontal

Photo 1
Photo 1
Photo 2
Photo 2
Photo 3
Photo 3
Photo 4
Photo 4
Photo 5
Photo 5
scroll-area/horizontal
<%= render Shadcn::ScrollArea.new(class_name: "h-64 w-full max-w-md rounded-md border") do %>
  <pre class="p-4 text-sm"><code>import { ScrollArea } from "@/components/ui/scroll-area"

export function ScrollAreaDemo() {
  return (
    &lt;ScrollArea className="h-72 w-48 rounded-md border"&gt;
      &lt;div className="p-4"&gt;
        &lt;h4 className="mb-4 text-sm font-medium leading-none"&gt;
          Tags
        &lt;/h4&gt;
        {Array.from({ length: 50 }).map((_, i) =&gt; (
          &lt;div key={i} className="text-sm"&gt;
            v1.2.0-beta.{i}
          &lt;/div&gt;
        ))}
      &lt;/div&gt;
    &lt;/ScrollArea&gt;
  )
}</code></pre>
<% end %>

Both Directions

Column 1 Column 2 Column 3 Column 4 Column 5 Column 6
Row 1, Cell 1Row 1, Cell 2Row 1, Cell 3Row 1, Cell 4Row 1, Cell 5Row 1, Cell 6
Row 2, Cell 1Row 2, Cell 2Row 2, Cell 3Row 2, Cell 4Row 2, Cell 5Row 2, Cell 6
Row 3, Cell 1Row 3, Cell 2Row 3, Cell 3Row 3, Cell 4Row 3, Cell 5Row 3, Cell 6
Row 4, Cell 1Row 4, Cell 2Row 4, Cell 3Row 4, Cell 4Row 4, Cell 5Row 4, Cell 6
Row 5, Cell 1Row 5, Cell 2Row 5, Cell 3Row 5, Cell 4Row 5, Cell 5Row 5, Cell 6
Row 6, Cell 1Row 6, Cell 2Row 6, Cell 3Row 6, Cell 4Row 6, Cell 5Row 6, Cell 6
Row 7, Cell 1Row 7, Cell 2Row 7, Cell 3Row 7, Cell 4Row 7, Cell 5Row 7, Cell 6
Row 8, Cell 1Row 8, Cell 2Row 8, Cell 3Row 8, Cell 4Row 8, Cell 5Row 8, Cell 6
Row 9, Cell 1Row 9, Cell 2Row 9, Cell 3Row 9, Cell 4Row 9, Cell 5Row 9, Cell 6
Row 10, Cell 1Row 10, Cell 2Row 10, Cell 3Row 10, Cell 4Row 10, Cell 5Row 10, Cell 6
scroll-area/both_directions
<%= render Shadcn::ScrollArea.new(class_name: "h-64 w-full max-w-md rounded-md border") do %>
  <pre class="p-4 text-sm"><code>import { ScrollArea } from "@/components/ui/scroll-area"

export function ScrollAreaDemo() {
  return (
    &lt;ScrollArea className="h-72 w-48 rounded-md border"&gt;
      &lt;div className="p-4"&gt;
        &lt;h4 className="mb-4 text-sm font-medium leading-none"&gt;
          Tags
        &lt;/h4&gt;
        {Array.from({ length: 50 }).map((_, i) =&gt; (
          &lt;div key={i} className="text-sm"&gt;
            v1.2.0-beta.{i}
          &lt;/div&gt;
        ))}
      &lt;/div&gt;
    &lt;/ScrollArea&gt;
  )
}</code></pre>
<% end %>

Scrollbar Types

<div> <h4 class="mb-2 text-sm font-medium">Scrollbar Type: Hover</h4> <p class="text-sm text-muted-foreground mb-2"> This scroll area uses the "hover" scrollbar type. </p> <ul class="text-sm space-y-1"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <li>Item 4</li> <li>Item 5</li> <li>Item 6</li> <li>Item 7</li> <li>Item 8</li> <li>Item 9</li> <li>Item 10</li> <li>Item 11</li> <li>Item 12</li> </ul> </div>
scroll-area/scrollbar_types
<%= render Shadcn::ScrollArea.new(class_name: "h-64 w-full max-w-md rounded-md border") do %>
  <pre class="p-4 text-sm"><code>import { ScrollArea } from "@/components/ui/scroll-area"

export function ScrollAreaDemo() {
  return (
    &lt;ScrollArea className="h-72 w-48 rounded-md border"&gt;
      &lt;div className="p-4"&gt;
        &lt;h4 className="mb-4 text-sm font-medium leading-none"&gt;
          Tags
        &lt;/h4&gt;
        {Array.from({ length: 50 }).map((_, i) =&gt; (
          &lt;div key={i} className="text-sm"&gt;
            v1.2.0-beta.{i}
          &lt;/div&gt;
        ))}
      &lt;/div&gt;
    &lt;/ScrollArea&gt;
  )
}</code></pre>
<% end %>

Code Block

import { ScrollArea } from "@/components/ui/scroll-area"

export function ScrollAreaDemo() {
  return (
    <ScrollArea className="h-72 w-48 rounded-md border">
      <div className="p-4">
        <h4 className="mb-4 text-sm font-medium leading-none">
          Tags
        </h4>
        {Array.from({ length: 50 }).map((_, i) => (
          <div key={i} className="text-sm">
            v1.2.0-beta.{i}
          </div>
        ))}
      </div>
    </ScrollArea>
  )
}
scroll-area/code_block
<%= render Shadcn::ScrollArea.new(class_name: "h-64 w-full max-w-md rounded-md border") do %>
  <pre class="p-4 text-sm"><code>import { ScrollArea } from "@/components/ui/scroll-area"

export function ScrollAreaDemo() {
  return (
    &lt;ScrollArea className="h-72 w-48 rounded-md border"&gt;
      &lt;div className="p-4"&gt;
        &lt;h4 className="mb-4 text-sm font-medium leading-none"&gt;
          Tags
        &lt;/h4&gt;
        {Array.from({ length: 50 }).map((_, i) =&gt; (
          &lt;div key={i} className="text-sm"&gt;
            v1.2.0-beta.{i}
          &lt;/div&gt;
        ))}
      &lt;/div&gt;
    &lt;/ScrollArea&gt;
  )
}</code></pre>
<% end %>

API Reference

API Reference

Prop Type Default Description
orientation Symbol :vertical Scroll orientation (:vertical, :horizontal, :both)
type Symbol :hover When to show scrollbar (:auto, :always, :scroll, :hover)
class_name String nil Additional CSS classes to apply to the scroll area container

Orientation Options

Value Description
:vertical Vertical scrolling only (default)
:horizontal Horizontal scrolling only
:both Both vertical and horizontal scrolling

Type Options

Value Description
:hover Show scrollbar on hover (default)
:always Always show scrollbar
:scroll Show scrollbar only when scrolling
:auto Browser default behavior

Accessibility

  • The scroll area maintains native scrolling behavior for keyboard navigation
  • Supports standard scroll keyboard shortcuts (arrow keys, Page Up/Down, Home/End)
  • Custom scrollbars are purely visual enhancements and don't affect accessibility
  • Screen readers treat the content as a normal scrollable region
  • The component preserves focus management within the scrollable area