media-captions-button
Accessible captions toggle button with availability detection and state reflection
Anatomy
<CaptionsButton /><media-captions-button></media-captions-button>Behavior
Toggles captions and subtitles on and off. The button checks the media’s text track list for tracks with kind="captions" or kind="subtitles" and reflects availability via data-availability.
When no caption or subtitle tracks are present, data-availability="unavailable" is set. Use this to hide the button when there are no tracks to toggle.
When menuTrigger is enabled and multiple caption or subtitle tracks are available, activation opens the linked captions menu instead of toggling captions directly. React enables menuTrigger automatically when a CaptionsButton is rendered inside Menu.Trigger.
Styling
Style the button based on active state:
media-captions-button[data-active] .icon-on { display: inline; }
media-captions-button:not([data-active]) .icon-off { display: inline; }Hide when no caption tracks are available:
media-captions-button[data-availability="unavailable"] {
display: none;
}Accessibility
Renders a <button> with an automatic aria-label: “Disable captions” when active, “Enable captions” when inactive. Override with the label prop. Keyboard activation: Enter / Space.
In menu-trigger mode, the button behaves as a menu trigger and reflects menu state through the trigger attributes.
Examples
Basic Usage
import { CaptionsButton, createPlayer } from '@videojs/react';
import { Video, videoFeatures } from '@videojs/react/video';
const Player = createPlayer({ features: videoFeatures });
export default function BasicUsage() {
return (
<Player.Provider>
<Player.Container className="media-container">
<Video
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4"
autoPlay
muted
playsInline
loop
>
<track kind="captions" src="/docs/demos/captions-button/captions.vtt" srcLang="en" label="English" />
</Video>
<CaptionsButton
className="media-captions-button"
render={(props, state) => (
<button {...props}>{state.subtitlesShowing ? 'Captions Off' : 'Captions On'}</button>
)}
/>
</Player.Container>
</Player.Provider>
);
}
.media-container {
position: relative;
}
.media-container video {
width: 100%;
}
.media-captions-button {
position: absolute;
bottom: 10px;
left: 10px;
padding-block: 8px;
padding-inline: 20px;
color: black;
cursor: pointer;
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 9999px;
backdrop-filter: blur(10px);
}
<video-player class="video-player">
<media-container>
<video
src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4"
autoplay
muted
playsinline
loop
>
<track kind="captions" src="/docs/demos/captions-button/captions.vtt" srclang="en" label="English" />
</video>
<media-captions-button class="media-captions-button">
<span class="active">Captions Off</span>
<span class="inactive">Captions On</span>
</media-captions-button>
</media-container>
</video-player>
.video-player {
position: relative;
}
.video-player video {
width: 100%;
}
.media-captions-button {
position: absolute;
bottom: 10px;
left: 10px;
padding-block: 8px;
padding-inline: 20px;
color: black;
cursor: pointer;
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 9999px;
backdrop-filter: blur(10px);
}
.media-captions-button .active {
display: none;
}
.media-captions-button .inactive {
display: none;
}
.media-captions-button[data-active] .active {
display: inline;
}
.media-captions-button:not([data-active]) .inactive {
display: inline;
}
import '@videojs/html/video/player';
import '@videojs/html/ui/captions-button';
API Reference
Props
| Prop | Type | Default | Details |
|---|---|---|---|
disabled | boolean | false | |
| |||
label | string | function | '' | |
| |||
menuTrigger | boolean | false | |
| |||
State
render, className, and style props.
| Property | Type | Details |
|---|---|---|
availability | 'available' | 'unavailable' | |
subtitlesShowing | boolean | |
| ||
label | string | |
Data attributes
| Attribute | Type | Details |
|---|---|---|
data-active | ||
| ||
data-availability | 'available' | 'unavailable' | |
| ||