Scroll Area
Augments native scroll functionality for custom, cross-browser styling.
Demo
Features
- Scrollbar sits on top of the scrollable content, taking up no space
- Native scrolling - no CSS transformation tricks
- Four visibility types: Hover, Scroll, Auto, Always
- Click on track to jump to position
- RTL (right-to-left) direction support
- Keyboard scrolling works automatically (native behavior)
Installation
dotnet add package SummitUIAnatomy
Import the components and structure them as follows:
<SmScrollAreaRoot>
<SmScrollAreaViewport>
<!-- Your scrollable content -->
</SmScrollAreaViewport>
<SmScrollAreaScrollbar Orientation="ScrollAreaOrientation.Vertical">
<SmScrollAreaThumb />
</SmScrollAreaScrollbar>
<SmScrollAreaScrollbar Orientation="ScrollAreaOrientation.Horizontal">
<SmScrollAreaThumb />
</SmScrollAreaScrollbar>
<SmScrollAreaCorner />
</SmScrollAreaRoot>Sub-components
ScrollAreaRoot
Contains all scroll area parts. Manages state and coordinates initialization.
ScrollAreaViewport
The scrollable viewport that wraps your content. Native scrollbars are hidden.
ScrollAreaScrollbar
The scrollbar track. Use the Orientation parameter for vertical or horizontal.
ScrollAreaThumb
The draggable thumb. Size and position are calculated automatically.
ScrollAreaCorner
The corner between vertical and horizontal scrollbars when both are present.
API Reference
ScrollAreaRoot
| Property | Type | Default | Description |
|---|---|---|---|
| Type | ScrollAreaType | Hover | Visibility behavior: Hover, Scroll, Auto, or Always |
| ScrollHideDelay | int | 600 | Delay in ms before hiding scrollbars (for Hover and Scroll types) |
| Dir | string? | null | Text direction (ltr/rtl). Auto-detected if not set |
| As | string | "div" | HTML element to render |
ScrollAreaViewport
| Property | Type | Default | Description |
|---|---|---|---|
| As | string | "div" | HTML element to render |
ScrollAreaScrollbar
| Property | Type | Default | Description |
|---|---|---|---|
| Orientation | ScrollAreaOrientation | Vertical | Scrollbar direction: Vertical or Horizontal |
| ForceMount | bool | false | Keep mounted regardless of visibility (useful for CSS animations) |
| As | string | "div" | HTML element to render |
ScrollAreaThumb
| Property | Type | Default | Description |
|---|---|---|---|
| As | string | "div" | HTML element to render |
ScrollAreaCorner
| Property | Type | Default | Description |
|---|---|---|---|
| As | string | "div" | HTML element to render |
Scroll Area Types
The Type parameter controls when scrollbars are visible.
Hover
Show scrollbars when hovering over the scroll area, hide after a delay. This is the default.
<SmScrollAreaRoot Type="ScrollAreaType.Hover">
<!-- Scrollbars appear on hover, hide after delay -->
</SmScrollAreaRoot>Scroll
Show scrollbars when actively scrolling, hide after a delay. Similar to macOS behavior.
<SmScrollAreaRoot Type="ScrollAreaType.Scroll">
<!-- Scrollbars appear when scrolling, hide after delay -->
</SmScrollAreaRoot>Auto
Show scrollbars when content overflows. Scrollbars remain visible while overflow exists.
<SmScrollAreaRoot Type="ScrollAreaType.Auto">
<!-- Scrollbars appear when content overflows -->
</SmScrollAreaRoot>Always
Always show scrollbars regardless of content overflow.
<SmScrollAreaRoot Type="ScrollAreaType.Always">
<!-- Scrollbars always visible -->
</SmScrollAreaRoot>Examples
Basic Vertical Scroll
<SmScrollAreaRoot Type="ScrollAreaType.Hover" class="h-72 w-48 rounded-lg border">
<SmScrollAreaViewport class="h-full w-full p-4">
<h4 class="mb-4 text-sm font-medium">Tags</h4>
@for (var i = 50; i > 0; i--)
{
<div class="mt-2 rounded bg-accent px-2 py-1 text-sm">
v1.2.0-beta.@i
</div>
}
</SmScrollAreaViewport>
<SmScrollAreaScrollbar Orientation="ScrollAreaOrientation.Vertical" class="scrollbar">
<SmScrollAreaThumb class="thumb" />
</SmScrollAreaScrollbar>
</SmScrollAreaRoot>Horizontal Scroll
<SmScrollAreaRoot Type="ScrollAreaType.Hover" class="w-96 rounded-lg border">
<SmScrollAreaViewport class="h-full w-full">
<div class="flex gap-4 p-4" style="width: max-content;">
@for (var i = 1; i <= 20; i++)
{
<div class="h-20 w-24 shrink-0 rounded bg-accent flex items-center justify-center">
Card @i
</div>
}
</div>
</SmScrollAreaViewport>
<SmScrollAreaScrollbar Orientation="ScrollAreaOrientation.Horizontal" class="scrollbar-h">
<SmScrollAreaThumb class="thumb" />
</SmScrollAreaScrollbar>
</SmScrollAreaRoot>Both Scrollbars
Add both vertical and horizontal scrollbars with a corner element.
<SmScrollAreaRoot Type="ScrollAreaType.Auto" class="h-64 w-64 rounded-lg border">
<SmScrollAreaViewport class="h-full w-full">
<div style="width: 500px; height: 500px; padding: 1rem;">
Large content that overflows both directions...
</div>
</SmScrollAreaViewport>
<SmScrollAreaScrollbar Orientation="ScrollAreaOrientation.Vertical" class="scrollbar-v">
<SmScrollAreaThumb class="thumb" />
</SmScrollAreaScrollbar>
<SmScrollAreaScrollbar Orientation="ScrollAreaOrientation.Horizontal" class="scrollbar-h">
<SmScrollAreaThumb class="thumb" />
</SmScrollAreaScrollbar>
<SmScrollAreaCorner class="corner" />
</SmScrollAreaRoot>Custom Hide Delay
Customize how long scrollbars remain visible after interaction.
@* Scrollbars hide after 100ms instead of default 600ms *@
<SmScrollAreaRoot Type="ScrollAreaType.Hover" ScrollHideDelay="100">
...
</SmScrollAreaRoot>
@* Scrollbars stay visible longer (2 seconds) *@
<SmScrollAreaRoot Type="ScrollAreaType.Scroll" ScrollHideDelay="2000">
...
</SmScrollAreaRoot>Styling
Data Attributes
| Attribute | Values | Description |
|---|---|---|
| data-summit-scroll-area-root | present | Present on the root element |
| data-summit-scroll-area-viewport | present | Present on the viewport element |
| data-summit-scroll-area-scrollbar | present | Present on scrollbar elements |
| data-summit-scroll-area-thumb | present | Present on thumb elements |
| data-summit-scroll-area-corner | present | Present on the corner element |
| data-orientation | "vertical" | "horizontal" | Scrollbar orientation |
| data-state | "visible" | "hidden" | Current visibility state of scrollbar/thumb |
CSS Example
The component is headless - you need to provide your own styles.
/* Root container */
.scroll-area {
position: relative;
overflow: hidden;
}
/* Viewport - scrollable area */
.scroll-area [data-summit-scroll-area-viewport] {
height: 100%;
width: 100%;
}
/* Vertical scrollbar track */
.scrollbar-v {
position: absolute;
top: 4px;
right: 4px;
bottom: 4px;
width: 8px;
border-radius: 9999px;
}
/* Horizontal scrollbar track */
.scrollbar-h {
position: absolute;
left: 4px;
right: 4px;
bottom: 4px;
height: 8px;
border-radius: 9999px;
}
/* Thumb */
.thumb {
flex: 1;
background-color: rgba(0, 0, 0, 0.3);
border-radius: 9999px;
}
.thumb:hover {
background-color: rgba(0, 0, 0, 0.5);
}
/* Visibility animation */
[data-summit-scroll-area-scrollbar][data-state="hidden"] {
opacity: 0;
transition: opacity 200ms;
}
[data-summit-scroll-area-scrollbar][data-state="visible"] {
opacity: 1;
transition: opacity 200ms;
}
/* Corner between scrollbars */
.corner {
position: absolute;
right: 0;
bottom: 0;
width: 8px;
height: 8px;
background-color: rgba(0, 0, 0, 0.1);
}RTL Support
Scrollbar positioning adapts to text direction automatically.
/* RTL support - vertical scrollbar on left side */
[dir="rtl"] .scrollbar-v {
right: auto;
left: 4px;
}
[dir="rtl"] .corner {
right: auto;
left: 0;
}Accessibility
The Scroll Area uses native scrolling, which means keyboard navigation works automatically. Users can scroll using:
Keyboard Navigation
| Key | Action |
|---|---|
| Arrow Keys | Scroll in the arrow direction |
| Page Up/Down | Scroll by page |
| Home/End | Scroll to start/end |
| Space | Scroll down by page (when focused) |