Reel
A horizontally scrolling container for browsing collections of cards or content frames.
Apply .reel to the scroll container and .snap-start to each frame. Add useReel when navigation controls or active-frame tracking are required.
Show code
import { useReel } from '@volvo-cars/react-headless';import { useRef } from 'react';
export function BasicReel() { const ref = useRef<HTMLDivElement>(null); const { reelProps } = useReel({ ref });
return ( <section ref={ref} className="reel gap-x-gridded-element" aria-label="Example frames" {...reelProps} > {Array.from({ length: 8 }, (_, i) => i + 1).map((frame) => ( <div key={frame} className="snap-start flex items-center justify-center bg-secondary p-24 shape-default" style={{ minWidth: '12rem', minHeight: '8rem' }} > Frame {frame} </div> ))} </section> );}Navigation arrows
Section titled “Navigation arrows”Spread previousButtonProps and nextButtonProps onto icon buttons to add back/forward navigation. The hook manages disabled state and hides the buttons from assistive technology since the scroll container is already keyboard-navigable.
Card content
Section titled “Card content”Reels work well for browsing product cards. Set a width on each card and use flex-shrink-0 to prevent them from collapsing. The last card should always be partially visible to indicate more content.
Hidden scrollbar
Section titled “Hidden scrollbar”Add the .scrollbar-none utility class to hide the native scrollbar. Only use this when you provide other visual indicators (like navigation arrows) that more content is available off-screen.
CSS-only
Section titled “CSS-only”The .reel class provides horizontal scrolling with snap points without JavaScript. This is useful for server-rendered content or simple layouts that don’t need navigation controls.
Show code
<section class="reel gap-x-gridded-element" aria-label="Example frames"> <div class="snap-start flex items-center justify-center bg-secondary p-24 shape-default" style="min-width: 12rem; min-height: 8rem" > Frame 1 </div> <div class="snap-start flex items-center justify-center bg-secondary p-24 shape-default" style="min-width: 12rem; min-height: 8rem" > Frame 2 </div> <div class="snap-start flex items-center justify-center bg-secondary p-24 shape-default" style="min-width: 12rem; min-height: 8rem" > Frame 3 </div> <div class="snap-start flex items-center justify-center bg-secondary p-24 shape-default" style="min-width: 12rem; min-height: 8rem" > Frame 4 </div> <div class="snap-start flex items-center justify-center bg-secondary p-24 shape-default" style="min-width: 12rem; min-height: 8rem" > Frame 5 </div> <div class="snap-start flex items-center justify-center bg-secondary p-24 shape-default" style="min-width: 12rem; min-height: 8rem" > Frame 6 </div> <div class="snap-start flex items-center justify-center bg-secondary p-24 shape-default" style="min-width: 12rem; min-height: 8rem" > Frame 7 </div> <div class="snap-start flex items-center justify-center bg-secondary p-24 shape-default" style="min-width: 12rem; min-height: 8rem" > Frame 8 </div></section>Keyboard navigation
Section titled “Keyboard navigation”- Arrow Left / Right: scroll through frames when the reel has focus.
- Tab: moves focus to focusable children within frames, or to the reel container itself if no focusable children exist.
- The
useReelhook automatically setstabIndex={0}on the reel container when it has no focusable children, ensuring keyboard users can scroll with arrow keys.
Accessibility
Section titled “Accessibility”Key consumer responsibilities from the WCAG audit:
- Labelling: provide
aria-labeloraria-labelledbyon the scrollable container so screen readers can announce its purpose. - Navigation buttons:
previousButtonPropsandnextButtonPropsincludearia-hidden="true"since the reel is already keyboard-navigable. - Focus management: with focusable children (links, buttons), keyboard users navigate by focusing each item. Without focusable children,
useReelmakes the container itself focusable. - Reduced motion: the
.reelclass respectsprefers-reduced-motionby disabling smooth scrolling.
See the useReel hooks documentation for full API reference, options, and return values.