Scrubber

The <ef-scrubber> element is a timeline scrubbing control that allows users to seek through video content by dragging or clicking on a progress bar. It automatically syncs with the playback state and can be extensively customized through CSS.

Basic Usage

<ef-preview>
  <ef-timegroup slot="canvas" mode="contain" className="w-[1920px] h-[1080px]">
    <ef-video src="/assets/video.mp4"></ef-video>
  </ef-timegroup>
  
  <div slot="controls">
    <ef-scrubber></ef-scrubber>
  </div>
</ef-preview>

How It Works

The scrubber consumes timing context (current time and duration) from its ancestor <ef-preview>, <ef-workbench>, or <ef-controls> element, or from a targeted element. When the user interacts with the scrubber:

  1. Click anywhere on the track to jump to that time
  2. Drag the handle to scrub through the timeline
  3. The scrubber updates the currentTimeMs in context
  4. All connected media elements seek to the new time

Learn More: This element uses the Target system to find controllable elements. See Understanding Temporal Elements for details.

Properties

target

Type: string
Default: ""

Optional ID of a temporal element to control. If not provided, the control will use context from its nearest ancestor (<ef-preview>, <ef-workbench>, or <ef-controls>).

Example:

<ef-scrubber target="my-video"></ef-scrubber>

Styling

CSS Custom Properties

The scrubber can be customized using CSS custom properties:

ef-scrubber {
  --ef-scrubber-height: 6px;
  --ef-scrubber-background: rgb(209 213 219);
  --ef-scrubber-progress-color: rgb(37 99 235);
  --ef-scrubber-handle-size: 16px;
  width: 100%;
}

--ef-scrubber-height

Type: CSS custom property
Default: 4px

Height of the scrubber track.

--ef-scrubber-background

Type: CSS custom property
Default: rgb(209 213 219)

Background color of the full track (unplayed portion).

--ef-scrubber-progress-color

Type: CSS custom property
Default: rgb(37 99 235)

Color of the progress indicator and handle.

--ef-scrubber-handle-size

Type: CSS custom property
Default: 12px

Size (width and height) of the draggable handle.

CSS Parts

For advanced styling, the scrubber exposes CSS parts:

ef-scrubber::part(scrubber) {
  /* Style the track container */
  border-radius: 4px;
}

ef-scrubber::part(progress) {
  /* Style the progress indicator */
  background: linear-gradient(90deg, #3b82f6, #8b5cf6);
}

ef-scrubber::part(handle) {
  /* Style the draggable handle */
  border: 2px solid white;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

Examples

Custom Styled Scrubber

<style>
  .custom-scrubber {
    --ef-scrubber-height: 8px;
    --ef-scrubber-background: #1f2937;
    --ef-scrubber-progress-color: #10b981;
    --ef-scrubber-handle-size: 18px;
    width: 100%;
  }
  
  .custom-scrubber::part(scrubber) {
    border-radius: 8px;
  }
  
  .custom-scrubber::part(handle) {
    border: 3px solid white;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
  }
</style>

<ef-scrubber class="custom-scrubber"></ef-scrubber>

Minimal Scrubber

<style>
  .minimal-scrubber {
    --ef-scrubber-height: 2px;
    --ef-scrubber-background: rgba(255, 255, 255, 0.2);
    --ef-scrubber-progress-color: white;
    --ef-scrubber-handle-size: 0px; /* Hide handle */
  }
</style>

<ef-scrubber class="minimal-scrubber"></ef-scrubber>

Gradient Progress

<style>
  .gradient-scrubber::part(progress) {
    background: linear-gradient(
      90deg,
      #ec4899,
      #8b5cf6,
      #3b82f6,
      #10b981
    );
  }
</style>

<ef-scrubber class="gradient-scrubber"></ef-scrubber>

With Labels

<div className="scrubber-container">
  <div className="flex justify-between text-xs text-gray-600 mb-1">
    <span>0:00</span>
    <span>Current Time</span>
    <span>2:30</span>
  </div>
  <ef-scrubber></ef-scrubber>
</div>

Use Cases

Timeline Navigation

The primary use case is providing timeline navigation in video editors:

<ef-workbench>
  <ef-timegroup slot="canvas" mode="contain" className="w-[1920px] h-[1080px]">
    <ef-video src="/video.mp4"></ef-video>
  </ef-timegroup>
  
  <div slot="timeline" className="p-4">
    <ef-scrubber></ef-scrubber>
  </div>
</ef-workbench>

With Remote Controls

Use with <ef-controls> to place the scrubber anywhere:

<ef-preview id="my-video">...</ef-preview>

<div className="control-panel">
  <ef-controls target="my-video">
    <ef-scrubber></ef-scrubber>
    <ef-time-display></ef-time-display>
  </ef-controls>
</div>

Multiple Scrubbers

Have multiple scrubbers controlling the same video:

<ef-preview id="main-preview">
  <ef-timegroup slot="canvas" mode="contain" className="w-[1920px] h-[1080px]">
    <ef-video src="/video.mp4"></ef-video>
  </ef-timegroup>
  
  <div slot="controls">
    <!-- Main scrubber -->
    <ef-scrubber></ef-scrubber>
  </div>
</ef-preview>

<!-- Secondary scrubber in a different location -->
<ef-controls target="main-preview">
  <ef-scrubber className="mini-scrubber"></ef-scrubber>
</ef-controls>

Interaction Behavior

Click to Seek

Clicking anywhere on the scrubber track will immediately seek to that position in the timeline.

Drag to Scrub

Clicking and dragging the handle (or anywhere on the track) allows for smooth scrubbing through the content. The cursor changes to grab when hovering over the handle.

Mouse Move While Dragging

The scrubber listens to mouse move events during dragging, updating the playback position in real-time for responsive feedback.

Technical Notes

  • Uses TargetOrContextMixin to consume context from ancestors or a target
  • Consumes playingContext, currentTimeContext, and durationContext
  • Updates are throttled using requestAnimationFrame for smooth performance
  • Position is calculated as a percentage: currentTimeMs / durationMs
  • Pointer events are captured during dragging for better UX
  • Width is 100% by default, use CSS to constrain

Accessibility Considerations

The scrubber currently implements basic mouse interaction. For full accessibility:

  • Consider adding keyboard support (arrow keys for frame-by-frame, Page Up/Down for jumps)
  • Add ARIA labels for screen readers
  • Ensure sufficient color contrast for the handle
  • Consider adding focus indicators