Overview
Scena is accessible out of the box: every interactive element is keyboard-operable, exposes ARIA roles and attributes, and keeps a visible focus indicator. No extra configuration is required.
Keyboard navigation
| Element | Keys | Action |
|---|---|---|
| Video container (preview) | Enter / Space | Expand the widget |
| Progress bar | ArrowLeft / ArrowDown | Seek backward |
| Progress bar | ArrowRight / ArrowUp | Seek forward |
| Progress bar | Home / End | Jump to start / end |
| Control buttons | Enter / Space | Activate (play, pause, mute, close, CTA) |
The seek step is a fraction of the video duration, 0.05 (5%) by default. Configure it via the step prop of the progress component:
const scena = useScena({
config: {
videoProgress: {
step: 0.1 // seek 10% per keypress
}
}
});
Video controls and volume buttons appear on :focus-within as well as on hover, so keyboard users always see which control is focused.
Focus management
In preview mode the collapsed widget acts as a single button: the container is the only tab stop and its inner controls are skipped, so keyboard users don't tab through invisible elements.
When the widget expands, focus moves to the first available control — progress bar, then play/pause, then volume — depending on which components are enabled. When it collapses while focus is inside, focus returns to the container instead of being lost to the page.
Screen readers
The container exposes role="button", and the progress bar exposes role="slider" with aria-valuemin, aria-valuemax, and aria-valuenow. The current position is announced as human-readable time via aria-valuetext — for example 1:25 / 3:40 — instead of raw percentages.
Every interactive component accepts an aria prop to override or extend its attributes:
const scena = useScena({
config: {
videoContainer: {
aria: {
ariaLabel: 'Watch product demo'
}
},
videoControls: {
aria: {
play: { ariaLabel: 'Play demo video' },
pause: { ariaLabel: 'Pause demo video' }
}
}
}
});
The available attributes are defined by ComponentAriaProps:
interface ComponentAriaProps {
ariaLabel?: string;
ariaLabelledby?: string;
ariaDescribedby?: string;
ariaDisabled?: boolean;
ariaExpanded?: boolean;
ariaControls?: string;
ariaPressed?: ComponentAriaPressed;
ariaHaspopup?: ComponentAriaHaspopup;
}
See the component pages for the aria shape each component accepts — videoControls and videoVolume take per-button overrides.