# Video.js v10 — HTML Components (complete) > Every HTML components page in one file (about 115k tokens). Index with descriptions: https://videojs.org/docs/framework/html/reference/components/llms.txt --- # video-player The state boundary — creates a store and broadcasts it to all descendants. The `` element is the state boundary of your player. It creates a store and makes it available to every element inside it via context. Every player needs exactly one. ```html ``` ## How it’s created For most users, importing from `@videojs/html/video/player` registers a ready-to-use `` element with the standard video [features](https://videojs.org/docs/framework/html/guides/features) (bundled as a [preset](https://videojs.org/docs/framework/html/guides/presets)): ```ts import '@videojs/html/video/player'; ``` ```html ``` If you need a custom feature set or tag name, use `createPlayer()` to get the configured `PlayerElement`. Extend `ContainerElement` separately when you need custom container behavior: **my-player.ts** ```ts import { ContainerElement, createPlayer } from '@videojs/html'; import { videoFeatures } from '@videojs/html/video'; const { PlayerElement: MyPlayer } = createPlayer({ features: videoFeatures }); class MyContainer extends ContainerElement {} customElements.define('my-player', MyPlayer); customElements.define('my-container', MyContainer); ``` - [`createPlayer` reference](https://videojs.org/docs/framework/html/reference/api/html-create-player) ## What lives inside it Everything that needs player state goes inside ``: skins, containers, UI components, and your own custom components. Anything inside can access the store. ```html ``` ## No visual presence Packaged skins make `` boxless with `display: contents`. Width, height, positioning, transforms, and `getBoundingClientRect()` do not describe a visible player box there. Put layout and measurements on the [``](https://videojs.org/docs/framework/html/reference/components/player-container) instead. If you omit `` and import only the player and media components, those skin styles are not loaded. The player element still owns state, not layout, so add and style a `` instead of using the player itself as the layout surface. ## Accessing state Use the preset’s typed `PlayerController` to subscribe to store state from any custom element inside the player: **play-pause-button.ts** ```ts import { UIElement, selectPlayback } from '@videojs/html'; import { PlayerController } from '@videojs/html/video'; class PlayPauseButton extends UIElement { readonly #playback = new PlayerController(this, selectPlayback); connectedCallback() { super.connectedCallback(); this.addEventListener('click', this.#togglePlayback); } disconnectedCallback() { this.removeEventListener('click', this.#togglePlayback); super.disconnectedCallback(); } readonly #togglePlayback = () => { const playback = this.#playback.value; if (!playback) return; playback.paused ? playback.play() : playback.pause(); }; } customElements.define('play-pause-button', PlayPauseButton); ``` - [PlayerController reference](https://videojs.org/docs/framework/html/reference/api/player-controller) ## Extended player layouts The player’s scope can extend beyond the fullscreen target. Playlists, transcripts, sidebars, and other supplementary UI can live inside `` but outside ``. They still have full access to the store, but they won’t go fullscreen with the video. ```html ... ``` ## Lifecycle Video.js elements clean up after themselves when you remove them from the page: - `` and the UI elements destroy themselves two animation frames after they’re removed. Destroying the player also destroys its store. - Media components such as `` tear down their playback engine in a microtask after they’re removed. Moving an element synchronously, removing it and inserting it elsewhere with no `await` in between, triggers neither. To keep an element through a longer move, add the `keep-alive` attribute: ```html ``` `keep-alive` applies only to the element that carries it; descendants don’t inherit it. Set it on every Video.js element in the tree you move. Packaged skins don’t pass it to the controls inside them, so move a player that uses a packaged skin synchronously. An element with `keep-alive` is never destroyed automatically. When you’re finished with it, call `destroy()` on the player and UI elements, and `adapter.destroy()` on media components, which release their engine that way. A destroyed element can’t be reconnected; create a new one instead. --- # media-container The player's visual and interaction surface for layout, fullscreen, focus, and user activity. The `` is the player’s physical surface. It defines the visual boundary, registers the fullscreen and activity target, and gives gesture and hotkey elements a shared interaction surface. It lives inside a [``](https://videojs.org/docs/framework/html/reference/components/player). ```html ... ``` ## How it’s created Import the standard player entry point and the container. `video/player` registers only ``; `ui/container` registers ``: ```ts import '@videojs/html/video/player'; import '@videojs/html/ui/container'; ``` ```html ``` For custom behavior, extend the same `ContainerElement` used by the built-in player: **my-player.ts** ```ts import { ContainerElement } from '@videojs/html'; class MyContainer extends ContainerElement {} customElements.define('my-container', MyContainer); ``` Extending `ContainerElement` automatically registers the element with the nearest player when it connects and releases that registration when it disconnects. Import `@videojs/html/ui/container` when you only need to register the standard `` element. ## What it does ### Layout and fullscreen The container is the visual box around your media and controls. Put sizing, aspect ratio, positioning, and visual boundaries here — on ``, not ``. Place overlays inside it, use it as their positioning context, and measure it when your app needs the rendered player size. ```css .player-surface { position: relative; display: block; width: 640px; aspect-ratio: 16 / 9; } ``` ```html ... ``` When the user goes fullscreen, the **container** goes fullscreen — not the video element. This keeps controls and other UI visible on top of the video, since they’re children of the container. Custom video elements such as `` and `` do not create their own layout boxes: their inner `