Skip to content

ReferenceSliders

media-time-slider

A slider component for seeking through media playback time

Import

import '@videojs/html/ui/time-slider';
import '@videojs/html/ui/slider-track';
import '@videojs/html/ui/slider-buffer';
import '@videojs/html/ui/slider-fill';
import '@videojs/html/ui/slider-thumb';
import '@videojs/html/ui/slider-preview';
import '@videojs/html/ui/slider-thumbnail';
import '@videojs/html/ui/slider-value';
import '@videojs/html/ui/time-slider-chapters';
import '@videojs/html/ui/time-slider-chapter-title';

Anatomy

<media-time-slider>
  <media-slider-track>
    <media-slider-buffer></media-slider-buffer>
    <media-slider-fill></media-slider-fill>
  </media-slider-track>
  <media-slider-thumb></media-slider-thumb>
  <media-slider-preview>
    <media-time-slider-chapter-title></media-time-slider-chapter-title>
    <media-slider-value type="pointer"></media-slider-value>
  </media-slider-preview>
</media-time-slider>

Add <media-time-slider-chapters> to divide the slider track into sections. Each cue in the default kind="chapters" text track marks a chapter. Without chapter cues, one section covers the full slider.

<media-time-slider-chapters>
  <template>
    <div>
      <media-slider-track>
        <media-slider-buffer></media-slider-buffer>
        <media-slider-fill></media-slider-fill>
      </media-slider-track>
    </div>
  </template>
</media-time-slider-chapters>

The required template must contain exactly one HTML root element. It remains in the light DOM and is cloned for each normalized chapter range. When no chapter cues are available, it is cloned once as a full-width, cue-less range.

Behavior

Displays and controls the current playback position. Dragging the slider seeks the media. The fill level reflects currentTime / duration as a percentage, and the buffer level shows how much media has been buffered.

Value changes during drag are throttled via the changeThrottle prop (default 100ms) using a leading+trailing throttle to keep the UI responsive without overwhelming the media element.

Chapter cues are normalized into contiguous ranges. Any uncovered time becomes a gap range, so track geometry always spans the full duration. With no usable chapter cues, one gap range spans the entire slider. Gap ranges receive the same geometry styles but cannot be highlighted and have no chapter title.

Styling

Use CSS custom properties to style the fill, pointer, and buffer levels:

media-time-slider::before {
  width: var(--media-slider-fill);
}

Use data-seeking to style during active seek operations:

media-time-slider[data-seeking] {
  opacity: 0.8;
}

Each rendered chapter receives data-active while playback is inside it and data-highlighted while the pointer is inside an authored chapter. Its geometry and local progress are exposed through:

  • --media-slider-chapter-start
  • --media-slider-chapter-end
  • --media-slider-chapter-width
  • --media-slider-chapter-fill
  • --media-slider-chapter-buffer

The generated fill and buffer parts also inherit the slider-level --media-slider-fill and --media-slider-buffer values. This allows every chapter to render full-width progress planes and use its chapter bounds as a clip, keeping progress transitions continuous across segments.

Accessibility

Renders with role="slider" and an automatic aria-label that resolves to “Seek” from the active locale. Override with the label prop. Keyboard controls:

  • Arrow Left / Arrow Right: step by step increment
  • Page Up / Page Down: step by largeStep increment
  • Home: seek to start
  • End: seek to end

<media-time-slider-chapter-title> follows the pointer during pointer interaction. While the slider has keyboard focus, it follows the current playback position and announces chapter changes.

Examples

Nest sub-components for full control over the slider’s DOM structure. This example includes a track, fill bar, buffer indicator, draggable thumb, and a tooltip that shows the pointed-at time.

<video-player class="video-player">
  <media-container>
    <video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" autoplay muted playsinline loop></video>
    <media-time-slider class="media-time-slider">
      <media-slider-track class="media-slider-track">
        <media-slider-buffer class="media-slider-buffer"></media-slider-buffer>
        <media-slider-fill class="media-slider-fill"></media-slider-fill>
      </media-slider-track>
      <media-slider-thumb class="media-slider-thumb"></media-slider-thumb>
      <media-slider-value type="pointer" class="media-slider-value"></media-slider-value>
    </media-time-slider>
  </media-container>
</video-player>

With chapters

Add a default chapters track, then provide the markup used for each chapter. The deliberate one-minute gap in this example remains visible as an unlabelled, non-highlightable segment.

<video-player class="video-player">
  <media-container>
    <video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" autoplay muted playsinline loop crossorigin="anonymous">
      <track kind="chapters" src="/docs/demos/time-slider/chapters.vtt" srclang="en" default />
    </video>
    <media-time-slider class="media-time-slider">
      <media-time-slider-chapters class="media-slider-chapters">
        <template>
          <div class="media-slider-chapter">
            <media-slider-track class="media-slider-track">
              <media-slider-buffer class="media-slider-buffer"></media-slider-buffer>
              <media-slider-fill class="media-slider-fill"></media-slider-fill>
            </media-slider-track>
          </div>
        </template>
      </media-time-slider-chapters>
      <media-slider-thumb class="media-slider-thumb"></media-slider-thumb>
      <media-slider-preview class="media-slider-preview">
        <media-time-slider-chapter-title class="media-slider-chapter-title"></media-time-slider-chapter-title>
        <media-slider-value type="pointer"></media-slider-value>
      </media-slider-preview>
    </media-time-slider>
  </media-container>
</video-player>

API Reference

media-time-slider

Props

PropTypeDefaultDetails
changeThrottle
attribute change-throttle
number100
disabledboolean—
labelobject''
largeStep
attribute large-step
number—
orientation'horizontal' | 'vertical'—
pauseOnDrag
attribute pause-on-drag
booleanfalse
stepnumber—
thumbAlignment
attribute thumb-alignment
'center' | 'edge'—

State

State is reflected as data attributes for CSS styling.

PropertyTypeDetails
valuenumber
fillPercentnumber
pointerPercentnumber
draggingboolean
pointingboolean
interactiveboolean
orientation'horizontal' | 'vertical'
disabledboolean
thumbAlignment'center' | 'edge'
currentTimenumber
durationnumber
seekingboolean
bufferPercentnumber

Data attributes

AttributeDescription
data-seekingPresent when a seek operation is in progress.

CSS custom properties

VariableDescription
--media-slider-fillFill level percentage (0–100), representing current playback position.
--media-slider-pointerPointer position percentage (0–100), tracking the cursor along the slider.
--media-slider-bufferBuffer level percentage (0–100), indicating how much media has been buffered.

Events

EventDescription
drag-endFired when a pointer drag ends.
drag-startFired when a pointer drag starts.

media-time-slider-chapter-title

Displays the chapter title at the current pointer or keyboard position.

media-time-slider-chapters

Clones a light-DOM template once per normalized chapter range.

The required template must contain exactly one HTML root element. When no chapter cues are available, the template is cloned once for a full-duration range.

media-slider-buffer

Displays the buffered range on the slider track.

media-slider-fill

Displays the filled portion from start to the current value.

media-slider-preview

Positioning container for preview content that tracks the pointer along the slider.

Props

PropTypeDefaultDetails
overflow'clamp' | 'visible'—

Data attributes

AttributeTypeDetails
data-dragging—
data-pointing—
data-interactive—
data-orientation'horizontal' | 'vertical'
data-disabled—

media-slider-thumb

Draggable handle for setting the slider value. Receives focus and handles keyboard interaction.

Data attributes

AttributeTypeDetails
data-dragging—
data-pointing—
data-interactive—
data-orientation'horizontal' | 'vertical'
data-disabled—

media-slider-track

Contains the slider's visual track and interactive hit zone.

media-slider-value

Writes the formatted current or pointer slider value into its own text content, replacing any children.

Props

PropTypeDefaultDetails
type'current' | 'pointer'—

Data attributes

AttributeTypeDetails
data-dragging—
data-pointing—
data-interactive—
data-orientation'horizontal' | 'vertical'
data-disabled—