Controls
Containers for composing and auto-hiding player controls
Anatomy
Import the component and assemble its parts:
<Controls.Root>
<Controls.Group />
</Controls.Root><media-controls>
<media-controls-group></media-controls-group>
</media-controls>Examples
Basic Usage
import { Controls, createPlayer, features, PlayButton, Time, Video } from '@videojs/react';
import './BasicUsage.css';
const Player = createPlayer({ features: [...features.video] });
export default function BasicUsage() {
return (
<Player.Provider>
<Player.Container className="controls-basic">
<Video
src="https://stream.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4/highest.mp4"
autoPlay
muted
playsInline
loop
/>
<Controls.Root className="controls-basic__root">
<Controls.Group className="controls-basic__bottom" aria-label="Playback controls">
<PlayButton
className="controls-basic__button"
render={(props, state) => <button {...props}>{state.paused ? 'Play' : 'Pause'}</button>}
/>
<Time.Value type="current" className="controls-basic__time" />
</Controls.Group>
</Controls.Root>
</Player.Container>
</Player.Provider>
);
}
.controls-basic {
position: relative;
}
.controls-basic video {
width: 100%;
}
.controls-basic__root {
position: absolute;
inset: 0;
display: flex;
align-items: flex-end;
padding: 12px;
pointer-events: none;
background: linear-gradient(to top, rgba(0, 0, 0, 0.45), transparent 45%);
transition: opacity 0.25s;
}
.controls-basic__root:not([data-visible]) {
opacity: 0;
}
.controls-basic__bottom {
pointer-events: auto;
}
.controls-basic__time {
display: inline-flex;
align-items: center;
gap: 4px;
padding-block: 8px;
padding-inline: 16px;
border-radius: 9999px;
background: rgba(255, 255, 255, 0.75);
backdrop-filter: blur(10px);
color: black;
border: 1px solid rgba(255, 255, 255, 0.25);
font-size: 14px;
}
.controls-basic__bottom {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
.controls-basic__button {
padding-block: 8px;
background: rgba(255, 255, 255, 0.75);
backdrop-filter: blur(10px);
color: black;
border: 1px solid rgba(255, 255, 255, 0.25);
border-radius: 9999px;
padding-inline: 16px;
font-size: 14px;
cursor: pointer;
}
<video-player class="controls-basic">
<video
src="https://stream.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4/highest.mp4"
autoplay
muted
playsinline
loop
></video>
<media-controls class="controls-basic__root">
<media-controls-group class="controls-basic__bottom" aria-label="Playback controls">
<media-play-button class="controls-basic__button controls-basic__play">
<span class="show-when-paused">Play</span>
<span class="show-when-playing">Pause</span>
</media-play-button>
<media-time class="controls-basic__time" type="current"></media-time>
</media-controls-group>
</media-controls>
</video-player>
.controls-basic {
display: block;
position: relative;
}
.controls-basic video {
width: 100%;
}
.controls-basic__root {
position: absolute;
inset: 0;
display: flex;
align-items: flex-end;
padding: 12px;
pointer-events: none;
background: linear-gradient(to top, rgba(0, 0, 0, 0.45), transparent 45%);
transition: opacity 0.25s;
}
.controls-basic__root:not([data-visible]) {
opacity: 0;
}
.controls-basic__bottom {
pointer-events: auto;
}
.controls-basic__time {
display: inline-flex;
align-items: center;
gap: 4px;
padding-block: 8px;
padding-inline: 16px;
border-radius: 9999px;
background: rgba(255, 255, 255, 0.75);
backdrop-filter: blur(10px);
color: black;
border: 1px solid rgba(255, 255, 255, 0.25);
font-size: 14px;
}
.controls-basic__bottom {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
.controls-basic__button {
padding-block: 8px;
background: rgba(255, 255, 255, 0.75);
backdrop-filter: blur(10px);
color: black;
border: 1px solid rgba(255, 255, 255, 0.25);
border-radius: 9999px;
padding-inline: 16px;
font-size: 14px;
cursor: pointer;
}
.controls-basic__button .show-when-paused,
.controls-basic__button .show-when-playing {
display: none;
}
.controls-basic__play[data-paused] .show-when-paused {
display: inline;
}
.controls-basic__play:not([data-paused]) .show-when-playing {
display: inline;
}
import '@videojs/html/video/player';
import '@videojs/html/ui/controls';
import '@videojs/html/ui/play-button';
import '@videojs/html/ui/time';
API Reference
Root media-controls
Root container for player controls state and rendered control content.
State
State is accessible via the
render, className, and style props.
State is reflected as data attributes for CSS styling.
| Property | Type | |
|---|---|---|
visible | boolean | |
userActive | boolean |
Data attributes
| Attribute | Description |
|---|---|
data-visible | Present when controls are visible. |
data-user-active | Present when the user has recently interacted. |
Group media-controls-group
Layout group for related controls; sets role="group" when labeled.