ScrollViewer
ScrollViewer is a simple layout container that stretches to fill its parent's viewport and provides customizable scrollbar styles for scrollable content. It supports four scrollbar modes: normal (standard browser scrollbars), overlay (themed scrollbars always visible), whenMouseOver (scrollbars appear on hover), and whenScrolling (scrollbars appear during scrolling).
ScrollViewer is a layout container component that provides customizable scrollbar styling for its content. It stretches to fill 100% of its parent container's width and height, making it ideal for creating scrollable regions with enhanced visual control over scrollbar appearance.
Key features:
- Multiple scrollbar styles: Choose from browser default, themed, hover-activated, or scroll-activated scrollbars
- Automatic sizing: Stretches to fill parent container dimensions
- Theme integration: Uses shared theme variables for consistent styling across the application
- Performance optimized: Leverages OverlayScrollbars library for smooth, customizable scrolling
ScrollStyle Options:
The scrollStyle property controls how scrollbars are displayed:
normal: Uses the browser's native default scrollbaroverlay: Displays a themed scrollbar that is always visible and customizable via theme variableswhenMouseOver: Shows the scrollbar only when hovering over the scroll containerwhenScrolling: Displays the scrollbar only while scrolling, then fades out after 400ms of inactivity
Basic Usage:
<App scrollWholePage="false">
<ScrollViewer height="300px">
<Items data="{ Array.from({ length: 50 }).map((_, i) => ('Item #' + i)) }">
<Text value="{$item}" />
</Items>
</ScrollViewer>
</App>Normal Scrollbar (Browser Default):
Overlay Scrollbar (Always Visible, Themed):
The overlay scrollbar is always visible and uses theme variables for customization.
When Mouse Over (Hover-Activated):
The scrollbar appears only when you hover your mouse over the scroll container.
When Scrolling (Scroll-Activated):
The scrollbar appears only while actively scrolling and fades out after 400ms of inactivity.
With Custom Content:
ScrollViewer works with any content type, not just lists.
%-PROP-START headerTemplate
The headerTemplate property allows you to define a custom header that remains fixed at the top of the ScrollViewer.
<App scrollWholePage="false">
<ScrollViewer height="300px" backgroundColor="$color-surface-100">
<property name="headerTemplate">
<HStack
padding="$space-2"
backgroundColor="$color-surface-200"
borderBottom="1px solid $color-border-default"
>
<H4 value="Sticky Header" />
</HStack>
</property>
<Items
id="myList"
data="{ Array.from({ length: 100 }).map((_, i) => ('Item #' + i)) }"
>
<Text value="{$item}" padding="$space-2" />
</Items>
</ScrollViewer>
</App><App scrollWholePage="false">
<ScrollViewer height="300px" backgroundColor="$color-surface-100">
<property name="headerTemplate">
<HStack
padding="$space-2"
backgroundColor="$color-surface-200"
borderBottom="1px solid $color-border-default"
>
<H4 value="Sticky Header" />
</HStack>
</property>
<Items
id="myList"
data="{ Array.from({ length: 100 }).map((_, i) => ('Item #' + i)) }"
>
<Text value="{$item}" padding="$space-2" />
</Items>
</ScrollViewer>
</App>%-PROP-END
%-PROP-START footerTemplate
The footerTemplate property allows you to define a custom footer that remains fixed at the bottom of the ScrollViewer.
<App scrollWholePage="false">
<ScrollViewer height="300px" backgroundColor="$color-surface-100">
<Items
id="myList"
data="{ Array.from({ length: 100 }).map((_, i) => ('Item #' + i)) }"
>
<Text value="{$item}" padding="$space-2" />
</Items>
<property name="footerTemplate">
<HStack
padding="$space-2"
backgroundColor="$color-surface-200"
borderTop="1px solid $color-border-default"
horizontalAlignment="center"
>
<H4 value="Sticky Footer" />
</HStack>
</property>
</ScrollViewer>
</App><App scrollWholePage="false">
<ScrollViewer height="300px" backgroundColor="$color-surface-100">
<Items
id="myList"
data="{ Array.from({ length: 100 }).map((_, i) => ('Item #' + i)) }"
>
<Text value="{$item}" padding="$space-2" />
</Items>
<property name="footerTemplate">
<HStack
padding="$space-2"
backgroundColor="$color-surface-200"
borderTop="1px solid $color-border-default"
horizontalAlignment="center"
>
<H4 value="Sticky Footer" />
</HStack>
</property>
</ScrollViewer>
</App>%-PROP-END
Behaviors
This component supports the following behaviors:
| Behavior | Properties |
|---|---|
| Animation | animation, animationOptions |
| Bookmark | bookmark, bookmarkLevel, bookmarkTitle, bookmarkOmitFromToc |
| Component Label | label, labelPosition, labelWidth, labelBreak, required, enabled, shrinkToLabel, style, readOnly |
| Publish/Subscribe | subscribeToTopic |
| Tooltip | tooltip, tooltipMarkdown, tooltipOptions |
| Styling Variant | variant |
Properties
footerTemplate
An optional template that defines content always visible at the bottom of the ScrollViewer, outside the scrollable area. The footer sticks to the bottom while the inner content scrolls.
The footerTemplate property allows you to define a custom footer that remains fixed at the bottom of the ScrollViewer.
<App scrollWholePage="false">
<ScrollViewer height="300px" backgroundColor="$color-surface-100">
<Items
id="myList"
data="{ Array.from({ length: 100 }).map((_, i) => ('Item #' + i)) }"
>
<Text value="{$item}" padding="$space-2" />
</Items>
<property name="footerTemplate">
<HStack
padding="$space-2"
backgroundColor="$color-surface-200"
borderTop="1px solid $color-border-default"
horizontalAlignment="center"
>
<H4 value="Sticky Footer" />
</HStack>
</property>
</ScrollViewer>
</App><App scrollWholePage="false">
<ScrollViewer height="300px" backgroundColor="$color-surface-100">
<Items
id="myList"
data="{ Array.from({ length: 100 }).map((_, i) => ('Item #' + i)) }"
>
<Text value="{$item}" padding="$space-2" />
</Items>
<property name="footerTemplate">
<HStack
padding="$space-2"
backgroundColor="$color-surface-200"
borderTop="1px solid $color-border-default"
horizontalAlignment="center"
>
<H4 value="Sticky Footer" />
</HStack>
</property>
</ScrollViewer>
</App>headerTemplate
An optional template that defines content always visible at the top of the ScrollViewer, outside the scrollable area. The header sticks to the top while the inner content scrolls.
The headerTemplate property allows you to define a custom header that remains fixed at the top of the ScrollViewer.
<App scrollWholePage="false">
<ScrollViewer height="300px" backgroundColor="$color-surface-100">
<property name="headerTemplate">
<HStack
padding="$space-2"
backgroundColor="$color-surface-200"
borderBottom="1px solid $color-border-default"
>
<H4 value="Sticky Header" />
</HStack>
</property>
<Items
id="myList"
data="{ Array.from({ length: 100 }).map((_, i) => ('Item #' + i)) }"
>
<Text value="{$item}" padding="$space-2" />
</Items>
</ScrollViewer>
</App><App scrollWholePage="false">
<ScrollViewer height="300px" backgroundColor="$color-surface-100">
<property name="headerTemplate">
<HStack
padding="$space-2"
backgroundColor="$color-surface-200"
borderBottom="1px solid $color-border-default"
>
<H4 value="Sticky Header" />
</HStack>
</property>
<Items
id="myList"
data="{ Array.from({ length: 100 }).map((_, i) => ('Item #' + i)) }"
>
<Text value="{$item}" padding="$space-2" />
</Items>
</ScrollViewer>
</App>scrollStyle
default: "normal"
This property determines the scrollbar style and behavior. normal uses the standard browser scrollbar. overlay uses themed scrollbars that are always visible and can be customized via theme variables. whenMouseOver shows overlay scrollbars that appear when the mouse hovers over the scroll area and hide after 200ms when the mouse leaves. whenScrolling shows overlay scrollbars only during active scrolling and hides them after 400ms of inactivity.
Available values: normal (default), overlay, whenMouseOver, whenScrolling
showScrollerFade
default: true
When enabled, displays gradient fade indicators at the top and bottom of the scroll container to visually indicate that more content is available in those directions. The fade indicators automatically appear/disappear based on the current scroll position. Top fade shows when scrolled down from the top, bottom fade shows when not at the bottom. Only works with overlay scrollbar modes (not with normal mode).
Events
This component does not have any events.
Exposed Methods
This component does not expose any methods.
Styling
The ScrollViewer component uses shared theme variables with other layout containers that may act as scroll containers. Please note that these shared theme variables use the Scroller virtual component name, and not ScrollViewer.
Theme Variables
| Variable | Default Value (Light) | Default Value (Dark) |
|---|---|---|
| autoHideDelay-whenMouseOver-Scroller | 400 | 400 |
| autoHideDelay-whenScrolling-Scroller | 400 | 400 |
| backgroundColor-fade-Scroller | rgb(from $color-surface-0 r g b / 0.75) | rgb(from $color-surface-0 r g b / 0.75) |
| backgroundColor-handle-Scroller | $color-surface-200 | $color-surface-200 |
| backgroundColor-handle-Scroller--active | $color-surface-400 | $color-surface-400 |
| backgroundColor-handle-Scroller--hover | $color-surface-400 | $color-surface-400 |
| backgroundColor-track-Scroller | transparent | transparent |
| backgroundColor-track-Scroller--active | transparent | transparent |
| backgroundColor-track-Scroller--hover | transparent | transparent |
| border-handle-Scroller | none | none |
| border-handle-Scroller--active | none | none |
| border-handle-Scroller--hover | none | none |
| border-track-Scroller | none | none |
| border-track-Scroller--active | none | none |
| border-track-Scroller--hover | none | none |
| borderRadius-handle-Scroller | 10px | 10px |
| borderRadius-track-Scroller | 2px | 2px |
| height-fade-Scroller | 64px | 64px |
| maxSize-handle-Scroller | none | none |
| minSize-handle-Scroller | 33px | 33px |
| offset-handleInteractiveArea-Scroller | 4px | 4px |
| padding-axis-Scroller | 2px | 2px |
| padding-perpendicular-Scroller | 2px | 2px |
| size-perpendicularHandle-Scroller | 100% | 100% |
| size-perpendicularHandle-Scroller--active | 100% | 100% |
| size-perpendicularHandle-Scroller--hover | 100% | 100% |
| size-Scroller | 10px | 10px |
| transition-fade-Scroller | opacity 0.3s ease-in-out | opacity 0.3s ease-in-out |
| transition-handle-Scroller | none | none |
| transition-Scroller | opacity 0.15s, visibility 0.15s, top 0.15s, right 0.15s, bottom 0.15s, left 0.15s | opacity 0.15s, visibility 0.15s, top 0.15s, right 0.15s, bottom 0.15s, left 0.15s |
| transition-track-Scroller | none | none |
| transitionHandle-Scroller | opacity 0.15s, background-color 0.15s, border-color 0.15s, height 0.15s, width 0.15s | opacity 0.15s, background-color 0.15s, border-color 0.15s, height 0.15s, width 0.15s |
| transitionTrack-Scroller | opacity 0.15s, background-color 0.15s, border-color 0.15s | opacity 0.15s, background-color 0.15s, border-color 0.15s |
Variable Explanations
| Theme Variable | Description |
|---|---|
size-Scroller | The width (for vertical scrollbars) or height (for horizontal scrollbars) of the scrollbar |
padding-perpendicular-Scroller | The padding perpendicular to the scroll direction (e.g., top/bottom padding for vertical scrollbars) |
padding-axis-Scroller | The padding along the scroll direction (e.g., left/right padding for vertical scrollbars) |
borderRadius-track-Scroller | The border radius of the scrollbar track (the background area where the handle moves) |
backgroundColor-track-Scroller | The background color of the scrollbar track in its default state |
backgroundColor-track-Scroller--hover | The background color of the scrollbar track when hovered |
backgroundColor-track-Scroller--active | The background color of the scrollbar track when active/pressed |
border-track-Scroller | The border of the scrollbar track in its default state |
border-track-Scroller--hover | The border of the scrollbar track when hovered |
border-track-Scroller--active | The border of the scrollbar track when active/pressed |
borderRadius-handle-Scroller | The border radius of the scrollbar handle (the draggable thumb) |
backgroundColor-handle-Scroller | The background color of the scrollbar handle in its default state |
backgroundColor-handle-Scroller--hover | The background color of the scrollbar handle when hovered |
backgroundColor-handle-Scroller--active | The background color of the scrollbar handle when active/being dragged |
border-handle-Scroller | The border of the scrollbar handle in its default state |
border-handle-Scroller--hover | The border of the scrollbar handle when hovered |
border-handle-Scroller--active | The border of the scrollbar handle when active/being dragged |
minSize-handle-Scroller | The minimum size (width/height) of the scrollbar handle |
maxSize-handle-Scroller | The maximum size (width/height) of the scrollbar handle, or 'none' for no limit |
size-perpendicularHandle-Scroller | The size of the handle perpendicular to scroll direction (e.g., width of handle for vertical scrollbar) in default state |
size-perpendicularHandle-Scroller--hover | The size of the handle perpendicular to scroll direction when hovered |
size-perpendicularHandle-Scroller--active | The size of the handle perpendicular to scroll direction when active/being dragged |
offset-handleInteractiveArea-Scroller | Additional offset for the interactive area around the handle to make it easier to grab |
transition-Scroller | CSS transition for the scrollbar container (opacity, visibility, position changes) |
transitionTrack-Scroller | CSS transition for the scrollbar track (opacity, background-color, border-color) |
transitionHandle-Scroller | CSS transition for the scrollbar handle (opacity, background-color, border-color, size changes) |
height-fade-Scroller | The height of the fade overlay gradients at the top and bottom of the scroll container |
backgroundColor-fadeTop-Scroller | The background gradient for the top fade overlay (typically a gradient from opaque to transparent) |
backgroundColor-fadeBottom-Scroller | The background gradient for the bottom fade overlay (typically a gradient from transparent to opaque) |
transition-fade-Scroller | CSS transition for the fade overlays (opacity changes) |
autoHideDelay-whenMouseOver-Scroller | Delay in milliseconds before hiding scrollbar after mouse leaves in whenMouseOver mode |
autoHideDelay-whenScrolling-Scroller | Delay in milliseconds before hiding scrollbar after scrolling stops in whenScrolling mode |