Scroll Bar
A scroll bar is a UI component that allows users to navigate vertically or horizontally through content that extends beyond the visible area of a container. The ScrollBar component provides a headless scrollbar track element with proper ARIA scrollbar semantics, including orientation, value range, and accessible labeling.
This component renders the structural markup and ARIA attributes for a custom scrollbar. The consumer provides the visual thumb element as children and is responsible for implementing the scroll interaction logic (drag handling, position updates, and syncing with scrollable content). The component sets initial value attributes that the consumer should update dynamically.
Implementation Notes
- Renders a
<div>withrole="scrollbar"and full ARIA scrollbar attributes - Supports
"vertical"and"horizontal"orientations viaaria-orientation - Includes
aria-valuenow,aria-valuemin, andaria-valuemaxfor position tracking - Initial values are set to 0/0/100; consumer should update these dynamically
- The
labelprop provides the accessible name viaaria-label - Consumer provides the scrollbar thumb or track content via the
childrenslot - Rest props are spread onto the
<div>element
Props
orientation: "vertical" | "horizontal" (default: "vertical") -- the scrollbar direction, reflected inaria-orientationlabel: string (required) -- accessible name for the scrollbar viaaria-labelchildren: slot (required) -- scrollbar content, typically the draggable thumb element...restProps: unknown -- additional attributes spread onto the<div>element
Usage
Vertical scrollbar inside a chat message area:
<ScrollArea label="Chat messages" style="max-height: 400px; overflow: auto;">
<div class="messages"><!-- chat messages --></div>
<ScrollBar orientation="vertical" label="Chat scroll">
<div class="scroll-thumb"></div>
</ScrollBar>
</ScrollArea>
Horizontal scrollbar for a timeline strip:
<ScrollArea label="Project timeline" style="overflow-x: auto;">
<div class="timeline"><!-- timeline content --></div>
<ScrollBar orientation="horizontal" label="Timeline scroll">
<div class="scroll-thumb"></div>
</ScrollBar>
</ScrollArea>
Keyboard Interactions
- Arrow Up / Arrow Left: Scroll backward (decrease value) by a small increment
- Arrow Down / Arrow Right: Scroll forward (increase value) by a small increment
- Page Up: Scroll backward by a large increment
- Page Down: Scroll forward by a large increment
- Home: Scroll to the beginning (minimum value)
- End: Scroll to the end (maximum value)
Note: The consumer is responsible for implementing keyboard event handlers that update the scrollbar value.
ARIA
role="scrollbar"-- identifies the element as a scrollbar controlaria-label="..."-- provides the accessible name for the scrollbararia-orientation="vertical|horizontal"-- indicates the scrollbar directionaria-valuenow="0"-- the current scroll position (consumer should update dynamically)aria-valuemin="0"-- the minimum scroll valuearia-valuemax="100"-- the maximum scroll value
When to Use
- Use ScrollBar as a custom-styled scrollbar element within a ScrollArea container.
- Use ScrollBar when the native scrollbar appearance does not match your design system and you need visual consistency.
- Use ScrollBar to provide a scrollbar with full ARIA semantics for assistive technology users.
When Not to Use
- Do not use ScrollBar outside of a ScrollArea -- it requires the scroll container context for proper functionality.
- Do not use ScrollBar when native scrollbars are sufficient -- custom scrollbars add implementation complexity for drag handling and position synchronization.
Headless
The ScrollBar headless component provides a <div> with role="scrollbar", aria-orientation, aria-valuenow, aria-valuemin, aria-valuemax, and aria-label for full ARIA scrollbar semantics. The consumer provides the visual thumb element, drag interaction logic, and position synchronization with scrollable content.
Styles
The consumer provides all CSS styling. The component renders with a .scroll-bar class for targeting. No default styles are included — this is a fully headless component.
Testing
- Verify the component renders a
<div>element with classscroll-bar - Verify role="scrollbar"` -- identifies the element as a scrollbar control
- Verify aria-label="..."` -- provides the accessible name for the scrollbar
- Verify keyboard interactions work correctly
- Verify pass-through attributes are applied
Advice
- Designers: Make the scrollbar thumb large enough to grab easily, and ensure sufficient contrast between the thumb and track for visibility.
- Developers: Update
aria-valuenowdynamically as the user scrolls, and implement keyboard event handlers for arrow keys, Page Up/Down, Home, and End.
Related components
scroll-area— a scrollable container with custom scrollbar support
References
- WAI-ARIA scrollbar role: https://www.w3.org/TR/wai-aria-1.2/#scrollbar
- WAI-ARIA Practices - ScrollBar: https://www.w3.org/WAI/ARIA/apg/patterns/scrollbar/