Scroll Area
Augments native scroll functionality for custom, cross-browser styling.
Requires JavaScript
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 (
<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>
)
}</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 (
<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>
)
}</code></pre>
<% end %>
Examples
Vertical Scroll
The default orientation for scrollable content.
<%= 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.
<%= 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.
<%= 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
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 (
<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>
)
}</code></pre>
<% end %>
Horizontal
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 (
<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>
)
}</code></pre>
<% end %>
Both Directions
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 (
<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>
)
}</code></pre>
<% end %>
Scrollbar Types
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 (
<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>
)
}</code></pre>
<% end %>
Code Block
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 (
<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>
)
}</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
On This Page