FrameworkStyle

UI Components

Understanding Video.js v10's primitive-based component architecture

Video.js v10 components are built from unstyled UI primitives , taking inspiration from projects like shadcn/ui , Base UI , and Media Chrome . This approach gives you control over styling and behavior while handling the complex interactions for you.

UI primitives are React components with standard PascalCase naming: PlayButton, TimeSlider, VolumeSlider.

Core Principles

1. Primitive-Based Design

Each primitive represents at most one HTML element , without internal elements.

<TimeSlider.Root>
  <TimeSlider.Track>        {/* One element: the track */}
    <TimeSlider.Progress /> {/* One element: the progress bar */}
    <TimeSlider.Pointer />  {/* One element: hover indicator */}
  </TimeSlider.Track>
  <TimeSlider.Thumb />      {/* One element: the draggable thumb */}
</TimeSlider.Root>

2. Compound Components

Complex components are broken into smaller, composable pieces. This pattern is used for:

  • Sliders - Root, Track, Thumb, Progress, Pointer
  • Tooltips - Root, Trigger, Positioner, Popup
  • Popovers - Root, Trigger, Positioner, Popup

Each piece handles one concern, but they work together seamlessly.

3. Built-in Accessibility

Components include proper ARIA attributes, keyboard navigation, and focus management out of the box:

  • Buttons have correct roles and labels
  • Sliders support arrow key navigation
  • Focus is managed properly in tooltips and popovers
  • Screen readers get meaningful announcements

4. Data Attributes for Styling

Components expose state through data attributes, allowing pure CSS state styling:

/* Style based on state without JavaScript */
button[data-paused] {
  /* Paused state */
}

button:not([data-paused]) {
  /* Playing state */
}

Common data attributes:

  • data-paused - Present when media is paused
  • data-muted - Present when audio is muted
  • data-fullscreen - Present when in fullscreen mode
  • data-volume-level - Values: high, medium, low, off

Available Components

Simple Components

Single-element components that handle one piece of UI:

  • PlayButton - Play/pause toggle
  • MuteButton - Audio mute toggle
  • FullscreenButton - Fullscreen toggle
  • CurrentTimeDisplay - Current playback time
  • DurationDisplay - Total media duration
  • PreviewTimeDisplay - Time at hover position

Compound Components

Multi-element components for complex interactions:

  • TimeSlider - Seekable timeline with progress
  • VolumeSlider - Volume control slider
  • Tooltip - Hover tooltips with positioning
  • Popover - Click/hover popovers with collision detection

Context Binding

UI components automatically bind to the nearest player and media in the DOM tree. You don’t need to pass props or wire up event handlers—components discover their context.

<Provider>
  <FrostedSkin>
    <Video src="video.mp4" />
  </FrostedSkin>

  {/* This button automatically binds to the Provider above */}
  <PlayButton />
</Provider>

This pattern means you can:

  • Place controls anywhere inside the player tree
  • Create custom layouts without prop drilling
  • Mix skins and individual components as needed

See Also

  • Skins — Pre-composed component collections
  • Architecture — How components fit in the three-pillar model
  • Presets — Feature collections that power components
VideoJS