Skip to content

Styling the player ​

<ivkit-player> renders inside a shadow root, so page styles don't leak into it. You customize it in two ways:

  1. Custom properties (--iv-*) for colors, fonts and sizes.
  2. ::part() for anything else.

Custom properties ​

css
ivkit-player {
  --iv-accent: #ffd166;
  --iv-accent-contrast: #1b1b1f;
  --iv-font: 600 1rem/1.4 "Inter", sans-serif;
  --iv-radius: 12px;
  --iv-aspect-ratio: 4 / 3;
}
PropertyDefaultUsed for
--iv-aspect-ratio16 / 9Size of the player box.
--iv-radius0Corner radius of the player.
--iv-background#000Behind the video, including letterboxing.
--iv-color#fffText color.
--iv-font500 1rem/1.4 system-ui, sans-serifThe font shorthand.
--iv-accent#fffButtons and progress.
--iv-accent-contrast#111Text on accent-colored buttons.
--iv-button-radius999pxCorner radius of buttons.
--iv-focus-ring#4c9ffeKeyboard focus outline.
--iv-overlay-backgroundrgb(0 0 0 / 0.55)Behind the question, start, end and error screens.
--iv-question-font-size1.25emQuestion text and the error message.
--iv-controls-backgroundlinear-gradient(transparent, rgb(0 0 0 / 0.7))Behind the control bar.
--iv-hotspot-fillrgb(255 255 255 / 0.12)Hotspot fill.
--iv-hotspot-fill-hoverrgb(255 255 255 / 0.28)Hotspot fill on hover and focus.
--iv-hotspot-strokergb(255 255 255 / 0.85)Hotspot outline.
--iv-hotspot-stroke-width2pxHotspot outline width.
--iv-hotspot-stroke-dasharraynoneDashed hotspot outlines, e.g. 6 4.
--iv-hotspot-label-color#fffText of label hotspots.
--iv-hotspot-label-backgroundrgb(0 0 0 / 0.6)Behind the text of label hotspots.
--iv-hotspot-label-font-size0.85emText size of label hotspots.

Parts ​

Every element is exposed as a part:

css
ivkit-player::part(question) {
  backdrop-filter: blur(6px);
}

ivkit-player::part(option) {
  border-radius: 8px;
  text-transform: uppercase;
}
PartElement
stageWrapper of everything inside the player.
videoBoth stacked <video> elements.
question, question-text, options, optionQuestion overlay, its text, the options group and each option button. In a multiple question, options are toggle buttons, and the picked ones are also option-picked.
timerCountdown bar of a question with timeout. The bar inside shrinks with a CSS animation.
submitThe Confirm button of a multiple question. Disabled until the picked options are within its min and max.
start, start-buttonStart screen and its Play button.
end, replay-buttonEnd screen and its default Replay button.
error, error-text, retry-buttonError screen, shown when a scene's video fails, with its default message and "Try again" button.
controlsThe control bar.
controlEvery control button. Also play-button, mute-button and fullscreen-button.
progress, time, volumeSeek slider, time display and volume slider.
hotspotsLayer holding the hotspots.
hotspot, hotspot-<variant>Each hotspot button.
hotspot-shape, hotspot-labelThe SVG shape and the label inside each hotspot.
plugins, pluginLayer holding the plugins' layers, and each of them. Elements inside take the parts their plugin gives them.

Hotspots ​

Each hotspot gets the parts hotspot and hotspot-<variant>, so you can create your own variants:

ts
{ type: "hotspot", id: "coin", from: 4, label: "A coin", variant: "gold", area: { x: 0.4, y: 0.6, width: 0.08, height: 0.08 } }
css
ivkit-player::part(hotspot-gold) {
  --iv-hotspot-fill: rgb(255 209 102 / 0.35);
  --iv-hotspot-stroke: #ffd166;
  --iv-hotspot-stroke-dasharray: 4 3;
}

Variant names are lowercased, and characters other than letters, digits and - become -.

Slots ​

Replace the content of the start, end and error screens with slots:

html
<ivkit-player controls>
  <span slot="start">▶ Watch the story</span>
  <div slot="end">
    <p>Thanks for watching!</p>
    <a href="/next">Next episode</a>
  </div>
</ivkit-player>

The start slot goes inside the Play button, so it replaces only its label: keep links and other buttons out of it. The end slot replaces the default Replay button. Call player.restart() from your own button to play again.

The error slot replaces the default content of the error screen, shown when a scene's video fails. Call player.retry() from your own button to load it again.

Fullscreen ​

The control bar's fullscreen button, the f key and player.toggleFullscreen() put the whole player in fullscreen, so questions and hotspots come along.

On iPhone, where elements can't go fullscreen, the player covers the viewport instead and sets the pseudo-fullscreen attribute. Style that state with:

css
ivkit-player[pseudo-fullscreen] {
  /* e.g. hide page chrome that would show through */
}