Video
import "@taprootio/espalier/video";
<esp-video>
A native video player: a <video> element with a lazy poster, a fixed
aspect ratio, captions, native controls, and visible loading and error
states. It is never an iframe and never loads a third-party player.
Nothing but the poster loads until the visitor presses play, so a page of
videos costs one image request each. The play affordance over the poster is
a real button named from label or poster-alt.
Sources
The element plays src only where the browser reports it can play type.
type is an HLS master playlist by default, which Safari, iOS, and current
Chrome play natively; elsewhere fallback-src (an MP4) plays instead.
Espalier attaches no streaming library, so for a source every browser can
play, set type="video/mp4".
Captions
Give the element <track> children. A media element only reads its own
child tracks, so the element mirrors them into its video when it attaches
the source; kind, srclang, label, and default carry through. With
the default preload="none", no caption file loads before the visitor
presses play.
Autoplay
autoplay starts playback once the element is admitted (immediately, or
near the viewport with defer-offscreen). It always plays muted: while
autoplay is set the video stays muted whatever muted says, so a page
never starts sound unprompted. It does not start for a visitor who prefers
reduced motion, or where the browser blocks it; the poster and play button
remain.
Slots
<esp-video> has the following slots:
Default
<track> elements for captions, subtitles, descriptions, and chapters.
error
Replaces the error message shown over the poster.
Attributes
<esp-video> has the following attributes:
src
src has a default value of "".
The media URL: an HLS master playlist by default, or a file matching type.
type
type has a default value of "application/vnd.apple.mpegurl".
The media type of src, checked with canPlayType to choose between
src and fallback-src. video/mp4 plays as a plain file.
poster
poster has a default value of "".
Poster image URL, shown until playback starts and behind error messages.
poster-alt
poster-alt has a default value of "".
Describes the poster; names the play button when label is unset.
label
label has a default value of "".
The play button's accessible name. Defaults to Play video: <poster-alt>,
or Play video with no poster text.
aspect-ratio
aspect-ratio has a default value of "16 / 9".
The box's aspect ratio, as a positive number or number / number. Invalid
values fall back to 16 / 9.
preload
preload has a default value of "none".
How much media to load before play intent. none (the default) loads
only the poster. metadata and auto apply where the browser plays
type; the choice of the fallback over it still waits for play intent.
A preloaded source that fails switches to fallback-src at once.
autoplay
autoplay has a default value of false.
Start muted playback once admitted. Implies muted.
muted
muted has a default value of false.
Start muted. Always on while autoplay is set. Clearing it (or
autoplay) unmutes only a paused video; a playing one stays muted until
the visitor unmutes it.
loop
loop has a default value of false.
Restart from the beginning when playback ends.
playsinline
playsinline has a default value of false.
Play inline on iOS rather than entering full screen. Needed for inline autoplay there.
controls
controls has a default value of "native".
native (the default) shows the browser's controls once playback starts.
none shows none; use it only for short decorative loops, since a visitor
then has no way to pause.
defer-offscreen
defer-offscreen has a default value of false.
Defer everything — the poster, preload, and autoplay — until the
element is within 200px of the viewport. The poster is not rendered
before then, so the browser's own lazy-loading distance cannot fetch it
early.
fallback-src
fallback-src has a default value of "".
An MP4 played when the browser cannot play type, and tried once when
the primary source fails.
crossorigin
crossorigin has a default value of "".
CORS mode for the video's requests, as on <video crossorigin>. Needed
for caption tracks served from another origin.
surface-layer
surface-layer has a default value of undefined.
Declares the painted surface depth. Fields use the next local layer, capped at layer 4.
intent
intent has a default value of undefined.
The element's intent — its meaning: neutral
(no pin), or success, warning, danger, info — each pinned
to its fixed status family (blue for info), retunable per theme
via intents. On token-emitting controls a non-neutral intent pins the
filled-action pair to that family, derived over the governing
zone's theme; class-styled chrome (badges, callouts, status pills)
opts out of inline emission and renders its treatment from CSS
classes instead. An intent never repaints the surrounding zone,
which is what contexts are for. Removing the attribute restores
the element's own default intent.
context
context has a default value of undefined.
A theme-defined color zone. The selected context rebinds designer-facing roles and emits a complete, contrast-enforced semantic token table on this host for descendants to inherit.
Methods
<esp-video> has the following methods:
traverseToClosest
Traverse up the DOM tree to find the closest element that matches the selector. This method is aware of shadow DOM boundaries and will traverse through them to find the element.
Events
<esp-video> emits the following events:
esp-video-ready
esp-video-ready is of type CustomEvent<VideoReadyDetail>.
Bubbles across shadow boundaries once the attached source has loaded its metadata; detail is { src, mode, duration }. Fires once per attached source.
esp-video-play
esp-video-play is of type CustomEvent<VideoPlayDetail>.
Bubbles across shadow boundaries each time playback starts, or resumes after a pause, on the media's playing. Recovery from buffering or a seek is not reported, and a source that fails first reports no play; detail is { src, mode, currentTime, autoplay }.
esp-video-error
esp-video-error is of type CustomEvent<VideoErrorDetail>.
Bubbles across shadow boundaries when a source fails; detail is { src, mode, reason, message, fallback }. When fallback is true the element is already trying fallback-src.
CSS Parts
<esp-video> has the following CSS parts:
frame
The element's full box.
video
The native <video> element.
poster
The layer over the video holding the poster, play button, and messages.
poster-image
The poster <img>.
play
The play <button>, which covers the poster.
play-icon
The visible play disc inside the button.
message
The error message.
CSS Properties
<esp-video> has the following CSS properties:
--esp-video-surface
Background behind the video and an absent poster. Defaults to a near-black derived from --esp-color-text.
--esp-video-border-radius
Corner radius. Defaults to var(--esp-size-border-radius).
--esp-video-object-fit
How the video fills its box. Defaults to contain; the poster always covers.
--esp-video-accent
accent-color for the native controls, where the browser honors it. Defaults to var(--esp-color-primary).
--esp-video-focus-outline
Focus-visible outline on the play button, the video, and the error message. Defaults to 3px solid var(--esp-color-link).
--esp-video-play-size
Diameter of the play disc. Defaults to var(--esp-size-huge).
--esp-video-play-background
Fill of the play disc. Defaults to var(--esp-color-background) at 90% opacity.
--esp-video-play-color
Play glyph and loading-indicator color. Defaults to var(--esp-color-text).
--esp-video-message-background
Error message background. Defaults to var(--esp-color-background).
--esp-video-message-color
Error message text color. Defaults to var(--esp-color-text).
--esp-field-background
Background color of the shared field shell. Defaults to one layer above the nearest declared surface, capped at var(--esp-color-layer-4), or var(--esp-color-layer-2) without a declared surface. An explicit override wins.
--esp-field-border-color
Border color of the shared field shell. Defaults to var(--esp-color-border).
--esp-field-border-width
Border width of the shared field shell. Defaults to 1px.
--esp-field-text-color
Text color used inside the shared field shell. Defaults to var(--esp-color-text).
--esp-field-hover-bg
Hover background color of the shared field shell. Derived from --esp-field-background.
--esp-field-focus-bg
Focus background color of the shared field shell. Derived from --esp-field-background.
--esp-field-focus-shadow
Shadow color used for shared field focus treatment. Defaults to var(--esp-color-shadow).