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 scrollbar
  • overlay: Displays a themed scrollbar that is always visible and customizable via theme variables
  • whenMouseOver: Shows the scrollbar only when hovering over the scroll container
  • whenScrolling: 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):

ScrollStyle: Normal

Overlay Scrollbar (Always Visible, Themed):

The overlay scrollbar is always visible and uses theme variables for customization.

ScrollStyle: Overlay

When Mouse Over (Hover-Activated):

The scrollbar appears only when you hover your mouse over the scroll container.

ScrollStyle: When Mouse Over

When Scrolling (Scroll-Activated):

The scrollbar appears only while actively scrolling and fades out after 400ms of inactivity.

ScrollStyle: When Scrolling

With Custom Content:

ScrollViewer works with any content type, not just lists.

ScrollViewer with Custom Content

%-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>
ScrollViewer with Header
<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>
ScrollViewer with Footer
<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:

BehaviorProperties
Animationanimation, animationOptions
Bookmarkbookmark, bookmarkLevel, bookmarkTitle, bookmarkOmitFromToc
Component Labellabel, labelPosition, labelWidth, labelBreak, required, enabled, shrinkToLabel, style, readOnly
Publish/SubscribesubscribeToTopic
Tooltiptooltip, tooltipMarkdown, tooltipOptions
Styling Variantvariant

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>
ScrollViewer with Footer
<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>
ScrollViewer with Header
<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

VariableDefault Value (Light)Default Value (Dark)
autoHideDelay-whenMouseOver-Scroller400400
autoHideDelay-whenScrolling-Scroller400400
backgroundColor-fade-Scrollerrgb(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-Scrollertransparenttransparent
backgroundColor-track-Scroller--activetransparenttransparent
backgroundColor-track-Scroller--hovertransparenttransparent
border-handle-Scrollernonenone
border-handle-Scroller--activenonenone
border-handle-Scroller--hovernonenone
border-track-Scrollernonenone
border-track-Scroller--activenonenone
border-track-Scroller--hovernonenone
borderRadius-handle-Scroller10px10px
borderRadius-track-Scroller2px2px
height-fade-Scroller64px64px
maxSize-handle-Scrollernonenone
minSize-handle-Scroller33px33px
offset-handleInteractiveArea-Scroller4px4px
padding-axis-Scroller2px2px
padding-perpendicular-Scroller2px2px
size-perpendicularHandle-Scroller100%100%
size-perpendicularHandle-Scroller--active100%100%
size-perpendicularHandle-Scroller--hover100%100%
size-Scroller10px10px
transition-fade-Scrolleropacity 0.3s ease-in-outopacity 0.3s ease-in-out
transition-handle-Scrollernonenone
transition-Scrolleropacity 0.15s, visibility 0.15s, top 0.15s, right 0.15s, bottom 0.15s, left 0.15sopacity 0.15s, visibility 0.15s, top 0.15s, right 0.15s, bottom 0.15s, left 0.15s
transition-track-Scrollernonenone
transitionHandle-Scrolleropacity 0.15s, background-color 0.15s, border-color 0.15s, height 0.15s, width 0.15sopacity 0.15s, background-color 0.15s, border-color 0.15s, height 0.15s, width 0.15s
transitionTrack-Scrolleropacity 0.15s, background-color 0.15s, border-color 0.15sopacity 0.15s, background-color 0.15s, border-color 0.15s

Variable Explanations

Theme VariableDescription
size-ScrollerThe width (for vertical scrollbars) or height (for horizontal scrollbars) of the scrollbar
padding-perpendicular-ScrollerThe padding perpendicular to the scroll direction (e.g., top/bottom padding for vertical scrollbars)
padding-axis-ScrollerThe padding along the scroll direction (e.g., left/right padding for vertical scrollbars)
borderRadius-track-ScrollerThe border radius of the scrollbar track (the background area where the handle moves)
backgroundColor-track-ScrollerThe background color of the scrollbar track in its default state
backgroundColor-track-Scroller--hoverThe background color of the scrollbar track when hovered
backgroundColor-track-Scroller--activeThe background color of the scrollbar track when active/pressed
border-track-ScrollerThe border of the scrollbar track in its default state
border-track-Scroller--hoverThe border of the scrollbar track when hovered
border-track-Scroller--activeThe border of the scrollbar track when active/pressed
borderRadius-handle-ScrollerThe border radius of the scrollbar handle (the draggable thumb)
backgroundColor-handle-ScrollerThe background color of the scrollbar handle in its default state
backgroundColor-handle-Scroller--hoverThe background color of the scrollbar handle when hovered
backgroundColor-handle-Scroller--activeThe background color of the scrollbar handle when active/being dragged
border-handle-ScrollerThe border of the scrollbar handle in its default state
border-handle-Scroller--hoverThe border of the scrollbar handle when hovered
border-handle-Scroller--activeThe border of the scrollbar handle when active/being dragged
minSize-handle-ScrollerThe minimum size (width/height) of the scrollbar handle
maxSize-handle-ScrollerThe maximum size (width/height) of the scrollbar handle, or 'none' for no limit
size-perpendicularHandle-ScrollerThe size of the handle perpendicular to scroll direction (e.g., width of handle for vertical scrollbar) in default state
size-perpendicularHandle-Scroller--hoverThe size of the handle perpendicular to scroll direction when hovered
size-perpendicularHandle-Scroller--activeThe size of the handle perpendicular to scroll direction when active/being dragged
offset-handleInteractiveArea-ScrollerAdditional offset for the interactive area around the handle to make it easier to grab
transition-ScrollerCSS transition for the scrollbar container (opacity, visibility, position changes)
transitionTrack-ScrollerCSS transition for the scrollbar track (opacity, background-color, border-color)
transitionHandle-ScrollerCSS transition for the scrollbar handle (opacity, background-color, border-color, size changes)
height-fade-ScrollerThe height of the fade overlay gradients at the top and bottom of the scroll container
backgroundColor-fadeTop-ScrollerThe background gradient for the top fade overlay (typically a gradient from opaque to transparent)
backgroundColor-fadeBottom-ScrollerThe background gradient for the bottom fade overlay (typically a gradient from transparent to opaque)
transition-fade-ScrollerCSS transition for the fade overlays (opacity changes)
autoHideDelay-whenMouseOver-ScrollerDelay in milliseconds before hiding scrollbar after mouse leaves in whenMouseOver mode
autoHideDelay-whenScrolling-ScrollerDelay in milliseconds before hiding scrollbar after scrolling stops in whenScrolling mode