HorizontalScroller
A horizontally scrollable content container. HorizontalScroller provides a region that scrolls horizontally with overflow, supporting mouse drag scrolling, touch swipe, and keyboard navigation.
This headless component uses a <div> element with role="region" and aria-label to create an accessible horizontally scrollable area.
Implementation Notes
- Uses
<div>element with classhorizontal-scroller - Content scrolls horizontally with overflow
- Consumer styles children for horizontal layout (flexbox or grid)
- Supports mouse drag scrolling, touch swipe, and keyboard navigation
- Optional scroll snap behavior via consumer CSS
tabindex="0"enables keyboard scrolling when the container is focused
Props
label: string (required) -- accessible label for the scrollable regionchildren: slot (required) -- horizontally arranged content...restProps: Any additional HTML attributes
Usage
<HorizontalScroller label="Photo gallery">
<img src="photo1.jpg" alt="Photo 1" />
<img src="photo2.jpg" alt="Photo 2" />
<img src="photo3.jpg" alt="Photo 3" />
</HorizontalScroller>
<HorizontalScroller label="Related articles">
<Card>
<h3>Article 1</h3>
<p>Summary of article 1.</p>
</Card>
<Card>
<h3>Article 2</h3>
<p>Summary of article 2.</p>
</Card>
<Card>
<h3>Article 3</h3>
<p>Summary of article 3.</p>
</Card>
</HorizontalScroller>
Keyboard Interactions
- Left/Right arrow keys scroll horizontally when the container is focused
- Tab moves to focusable children within the scrollable area
ARIA
role="region"witharia-labelfor the scrollable areaaria-roledescription="carousel"if applicabletabindex="0"for keyboard scrolling
When to Use
- Use for horizontally scrolling galleries, card rows, or overflow content
- Use when content items are peers and benefit from a horizontal browsing experience
- Use when screen width cannot accommodate all items simultaneously
When Not to Use
- Do not use for primary navigation -- use TabBar or NavigationMenu instead
- Do not use when all items should be visible -- use a grid layout instead
- Do not use for content that must be consumed in sequence -- use Scroller for scrollytelling
Headless
This component provides a <div> element with role="region", aria-label, tabindex="0", and keyboard arrow key scrolling, with zero visual styling. The consumer is responsible for all CSS including horizontal layout (flexbox or grid), item sizing, scroll snap, scrollbar appearance, and responsive behavior.
Styles
The consumer provides all CSS styling. The component renders with a .horizontal-scroller class for targeting. No default styles are included -- this is a fully headless component.
Testing
- Verify the component renders a
<div>element with classhorizontal-scroller - Verify
role="region"is applied - Verify
aria-labelis applied - Verify
tabindex="0"is set for keyboard access - Verify Left/Right arrow keys scroll the container horizontally when focused
- Verify child content is rendered correctly
- Verify pass-through attributes are applied
Advice
- Designers: Provide visual cues that content extends beyond the visible area, such as partial visibility of the next item or scroll indicators. Consider how the layout adapts at different viewport widths.
- Developers: Always provide a descriptive
labelprop for screen reader users. Applyoverflow-x: autooroverflow-x: scrollvia CSS. Usescroll-snap-typefor snap behavior. Test with keyboard, mouse drag, and touch swipe interactions.
Related components
scroll-area— a scrollable container with custom scrollbar supportcarousel— a slideshow for cycling through content items
References
- Reuters Graphics HorizontalScroller
- WAI-ARIA carousel pattern: https://www.w3.org/WAI/ARIA/apg/patterns/carousel/
- CSS scroll snap: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_scroll_snap