Skip to content
FrameworkStyle

media-controls

Container component for composing and auto-hiding video player controls on user interaction

Import

import '@videojs/html/ui/controls';

Anatomy

Import the component and assemble its parts:

<media-controls>
  <media-controls-backdrop></media-controls-backdrop>
  <media-controls-content>
    <media-controls-group></media-controls-group>
  </media-controls-content>
</media-controls>

Behavior

If the user is active, or if the video is paused, this component will show controls. Otherwise, it will hide them after a short delay.

User activity is tracked via pointer movement, keyboard input, and focus events on the player container. On touch devices, a quick tap toggles visibility. mouseleave immediately sets the user as inactive.

Styling

Controls.Root is a state and context provider. Controls.Content / <media-controls-content> renders the interactive controls surface and receives its DOM props, ref, and controls state data attributes.

Controls.Backdrop / <media-controls-backdrop> is an optional presentational sibling of Content. It receives the same controls state data attributes, allowing its styling and transitions to be authored independently from the controls surface.

By default, controls have the following styles:

/* Click-through: clicks pass through controls to video beneath */
media-controls-content {
  pointer-events: none;
}

media-controls-group {
  pointer-events: auto;
}

media-controls-backdrop {
  position: absolute;
  inset: 0;
  transition: opacity 0.35s;
}

/* Fade transition */
media-controls-content {
  transition: opacity 0.25s;
}

media-controls-content:not([data-visible]) {
  opacity: 0;
}

media-controls-backdrop:not([data-visible]) {
  opacity: 0;
}

Accessibility

No ARIA role is applied to <media-controls> or <media-controls-content> — they provide state and layout, not a landmark. <media-controls-backdrop> is always hidden from assistive technology. <media-controls-group> automatically receives role="group" when an aria-label or aria-labelledby attribute is provided; otherwise no role is assigned.

Examples

Basic Usage

Play Pause
<video-player class="video-player">
  <media-container>
    <video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" autoplay muted playsinline loop></video>

    <media-controls>
      <media-controls-backdrop class="controls-backdrop"></media-controls-backdrop>
      <media-controls-content class="media-controls">
        <media-controls-group class="controls-group" aria-label="Playback controls">
          <media-play-button class="button media-play-button">
            <span class="paused">Play</span>
            <span class="playing">Pause</span>
          </media-play-button>
          <media-time class="time" type="current"></media-time>
        </media-controls-group>
      </media-controls-content>
    </media-controls>
  </media-container>
</video-player>

API Reference

media-controls

Manages controls state and provides it to the compound parts. Does not render an element.

Props

PropTypeDefaultDetails
visibility'auto' | 'always''auto'

State

State is reflected as data attributes for CSS styling.

PropertyTypeDetails
visibleboolean
userActiveboolean

Data attributes

AttributeTypeDetails
data-visible
data-user-active

media-controls-backdrop

Presentational layer behind player controls. Renders a <div> with the controls state data attributes so skins can style it without reaching across sibling components.

Data attributes

AttributeTypeDetails
data-visible
data-user-active

media-controls-content

Renders the interactive controls surface.

Data attributes

AttributeTypeDetails
data-visible
data-user-active

media-controls-group

Layout group for related controls; sets role="group" when labeled.

Data attributes

AttributeTypeDetails
data-visible
data-user-active