Controls

Playback control elements. Compose them freely against any timegroup.

Controls are unstyled building blocks — each one wires a single playback concern to a target timegroup. Use ef-controls as a context provider so child controls share a target without individual target attributes, or wire each element directly with target.

Interactive example

Elements

Customising ef-volume

ef-volume exposes CSS custom properties for styling the track without touching shadow DOM (it also exposes a slider CSS part if you'd rather style it directly). See ef-volume for the generated property table.

html
<ef-volume style="
  --ef-volume-height: 3px;
  --ef-volume-track-color: rgba(255,255,255,0.15);
  --ef-volume-fill-color: #e53935;
"></ef-volume>

In React:

tsx
<Volume
  className="w-16"
  style={{
    "--ef-volume-height": "3px",
    "--ef-volume-track-color": "rgba(255,255,255,0.15)",
    "--ef-volume-fill-color": "var(--brand-red)",
  } as React.CSSProperties}
/>

CSS Parts

ef-controls renders to light DOM (it's a pure context provider around your own slotted buttons), so it has no ::part() surface of its own — style your slotted <button> elements directly.

css
ef-scrubber::part(scrubber) { background: #1a1a2e; border-radius: 4px; }
ef-scrubber::part(progress) { background: #e94560; }
ef-scrubber::part(handle)   { background: #e94560; width: 14px; height: 14px; }

ef-volume::part(slider) { accent-color: #e53935; }

ef-resolution::part(select)       { background: #1a1a2e; border-color: rgba(255,255,255,0.2); }
ef-resolution::part(width-input),
ef-resolution::part(height-input) { background: #1a1a2e; border-color: rgba(255,255,255,0.2); }
ef-resolution::part(separator)    { opacity: 0.5; }