Scroll Area
ScrollArea - Phlex implementation
Examples
Default
Augments native scroll functionality for custom, cross-browser styling.
Tags
v1.2.0
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
<%= render "ui/scroll_area", classes: "h-[200px] w-[350px] rounded-md border p-4" do %>
<div class="space-y-4">
<h3 class="text-sm font-semibold">Tags</h3>
<div class="space-y-1">
<% %w[v1.2.0 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].each do |tag| %>
<div class="text-sm text-muted-foreground"><%= tag %></div>
<% end %>
</div>
</div>
<% end %>Tags
v1.2.0
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
<%= render "ui/scroll_area", classes: "h-[200px] w-[350px] rounded-md border p-4" do %>
<div class="space-y-4">
<h3 class="text-sm font-semibold">Tags</h3>
<div class="space-y-1">
<% %w[v1.2.0 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].each do |tag| %>
<div class="text-sm text-muted-foreground"><%= tag %></div>
<% end %>
</div>
</div>
<% end %>Tags
v1.2.0
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
<%= render "ui/scroll_area", classes: "h-[200px] w-[350px] rounded-md border p-4" do %>
<div class="space-y-4">
<h3 class="text-sm font-semibold">Tags</h3>
<div class="space-y-1">
<% %w[v1.2.0 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].each do |tag| %>
<div class="text-sm text-muted-foreground"><%= tag %></div>
<% end %>
</div>
</div>
<% end %>Horizontal
Horizontal scroll area for content that extends beyond the viewport width.
<div class="relative w-96 whitespace-nowrap rounded-md border" data-controller="ui--scroll-area">
<div data-ui-scroll-area-viewport data-ui--scroll-area-target="viewport" class="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1 focus-visible:ring-ring/50" style="overflow-x: scroll; overflow-y: hidden;">
<div style="min-width: 100%; display: table;">
<div class="flex w-max space-x-4 p-4">
<% 10.times do |i| %>
<div class="h-[150px] w-[150px] rounded-md bg-muted flex items-center justify-center shrink-0">
<span class="text-4xl font-semibold text-muted-foreground"><%= i + 1 %></span>
</div>
<% end %>
</div>
</div>
</div>
<%= render "ui/scroll_area/scrollbar", orientation: "horizontal" %>
</div><div class="relative w-96 whitespace-nowrap rounded-md border" data-controller="ui--scroll-area">
<div data-ui-scroll-area-viewport data-ui--scroll-area-target="viewport" class="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1 focus-visible:ring-ring/50" style="overflow-x: scroll; overflow-y: hidden;">
<div style="min-width: 100%; display: table;">
<div class="flex w-max space-x-4 p-4">
<% 10.times do |i| %>
<div class="h-[150px] w-[150px] rounded-md bg-muted flex items-center justify-center shrink-0">
<span class="text-4xl font-semibold text-muted-foreground"><%= i + 1 %></span>
</div>
<% end %>
</div>
</div>
</div>
<%= render "ui/scroll_area/scrollbar", orientation: "horizontal" %>
</div><div class="relative w-96 whitespace-nowrap rounded-md border" data-controller="ui--scroll-area">
<div data-ui-scroll-area-viewport data-ui--scroll-area-target="viewport" class="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1 focus-visible:ring-ring/50" style="overflow-x: scroll; overflow-y: hidden;">
<div style="min-width: 100%; display: table;">
<div class="flex w-max space-x-4 p-4">
<% 10.times do |i| %>
<div class="h-[150px] w-[150px] rounded-md bg-muted flex items-center justify-center shrink-0">
<span class="text-4xl font-semibold text-muted-foreground"><%= i + 1 %></span>
</div>
<% end %>
</div>
</div>
</div>
<%= render "ui/scroll_area/scrollbar", orientation: "horizontal" %>
</div>Custom Sizes
Scroll areas with different heights.
Small (h-24)
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Large (h-48)
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
<div class="grid grid-cols-2 gap-4">
<div>
<h3 class="text-sm font-medium mb-2">Small (h-24)</h3>
<%= render "ui/scroll_area", classes: "h-24 w-full rounded-md border p-4" do %>
<div class="space-y-2">
<% 10.times do |i| %>
<div class="text-sm">Item <%= i + 1 %></div>
<% end %>
</div>
<% end %>
</div>
<div>
<h3 class="text-sm font-medium mb-2">Large (h-48)</h3>
<%= render "ui/scroll_area", classes: "h-48 w-full rounded-md border p-4" do %>
<div class="space-y-2">
<% 20.times do |i| %>
<div class="text-sm">Item <%= i + 1 %></div>
<% end %>
</div>
<% end %>
</div>
</div>Small (h-24)
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Large (h-48)
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
<div class="grid grid-cols-2 gap-4">
<div>
<h3 class="text-sm font-medium mb-2">Small (h-24)</h3>
<%= render "ui/scroll_area", classes: "h-24 w-full rounded-md border p-4" do %>
<div class="space-y-2">
<% 10.times do |i| %>
<div class="text-sm">Item <%= i + 1 %></div>
<% end %>
</div>
<% end %>
</div>
<div>
<h3 class="text-sm font-medium mb-2">Large (h-48)</h3>
<%= render "ui/scroll_area", classes: "h-48 w-full rounded-md border p-4" do %>
<div class="space-y-2">
<% 20.times do |i| %>
<div class="text-sm">Item <%= i + 1 %></div>
<% end %>
</div>
<% end %>
</div>
</div>Small (h-24)
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Large (h-48)
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
<div class="grid grid-cols-2 gap-4">
<div>
<h3 class="text-sm font-medium mb-2">Small (h-24)</h3>
<%= render "ui/scroll_area", classes: "h-24 w-full rounded-md border p-4" do %>
<div class="space-y-2">
<% 10.times do |i| %>
<div class="text-sm">Item <%= i + 1 %></div>
<% end %>
</div>
<% end %>
</div>
<div>
<h3 class="text-sm font-medium mb-2">Large (h-48)</h3>
<%= render "ui/scroll_area", classes: "h-48 w-full rounded-md border p-4" do %>
<div class="space-y-2">
<% 20.times do |i| %>
<div class="text-sm">Item <%= i + 1 %></div>
<% end %>
</div>
<% end %>
</div>
</div>Features
- Custom styling with Tailwind classes
API Reference
Scroll Area
Augments native scroll functionality for custom, cross-browser styling.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| as_child | Boolean | false | When true, yields attributes to block instead of rendering wrapper |
| type | String | hover | The type |
| scroll_hide_delay | Integer | 600 | The scroll hide delay |
Viewport
Shared behavior for ScrollArea viewport across ERB, ViewComponent, and Phlex implementations.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| as_child | Boolean | false | When true, yields attributes to block instead of rendering wrapper |
Accessibility
Adheres to theScrollable Region WAI-ARIA design pattern
Implements the WAI-ARIA Scrollable Region pattern with proper roles, states, and keyboard navigation.
Keyboard Shortcuts
| Key | Description |
|---|---|
| Enter | Activates the focused element |
| End | Moves focus to last item |
JavaScript
Stimulus Controller
ui--scroll-areaValues
| Name | Type | Description |
|---|---|---|
| type | String | The type |
Actions
applyViewportOverflowinitializeScrollbarBehaviorinitializeHoverScrollbarinitializeScrollScrollbarinitializeAutoScrollbarinitializeAlwaysScrollbarstartScrollSyncsyncThumbPositionstartDrag