# media-container

The player's visual and interaction surface for layout, fullscreen, focus, and user activity.

The `<media-container>` 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 [`<video-player>`](https://videojs.org/docs/framework/html/reference/components/player).

```html
<video-player>
  <media-container>
    <video src="video.mp4"></video>
    <media-controls><media-controls-content>...</media-controls-content></media-controls>
  </media-container>
</video-player>
```

## How it’s created

Import the standard player entry point and the container. `video/player` registers only `<video-player>`; `ui/container` registers `<media-container>`:

```ts
import '@videojs/html/video/player';
import '@videojs/html/ui/container';
```

```html
<video-player>
  <media-container>
    <video src="video.mp4"></video>
  </media-container>
</video-player>
```

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 `<media-container>` 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 `<media-container>`, not `<video-player>`. 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
<media-container class="player-surface">
  <video src="video.mp4"></video>
  <media-controls><media-controls-content>...</media-controls-content></media-controls>
</media-container>
```

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 `<mux-video>` and `<hlsjs-video>` do not create their own layout boxes: their inner `<video>` fills the parent. Size and measure `<media-container>`, not `<mux-video>` or `<hlsjs-video>`. Native `<video>` and `<audio>` elements still render their own boxes.

### Media attachment

Media discovery is handled by the player provider, not the container. Custom media elements like `<hlsjs-video>` register themselves via context when they connect. Plain `<video>` and `<audio>` elements are tracked automatically, including when they are added, removed, or replaced after connection. No `slot="media"` attribute is needed.

### Interaction surface

The container is where user intent enters the player. It listens for physical interaction on its surface and translates that into player behavior:

- **User activity** — Mouse movement, touch, and keyboard activity within the container drive idle detection. This is how controls know when to show and hide.
- **Gestures** — Tap and double-tap actions, optionally limited by pointer type and left, center, or right region. Configured via the [`<media-gesture>`](https://videojs.org/docs/framework/html/reference/components/gesture) element.
- **Keyboard controls** — Spacebar to play/pause, arrow keys to seek, and other keyboard shortcuts scoped to the container. Configured via the `<media-hotkey>` element.

### Popup coordination

Each container owns one popup group. Opening a root [menu](https://videojs.org/docs/framework/html/reference/components/menu) or [popover](https://videojs.org/docs/framework/html/reference/components/popover) closes the previously open popup in that container. A popup rendered outside the container still manages its own open state, but it does not participate in the container’s group.

## Relationship to skins

A [skin](https://videojs.org/docs/framework/html/guides/skins) is a container plus UI controls. When you use a packaged skin, the container is built in — you don’t need to add one yourself.

Style `<video-skin>` for the player’s outer size and aspect ratio. Importing the skin registers the styles that make the built-in container fill that space and position the media, controls, poster, and overlays.

If you omit `<video-skin>` to build custom UI, render and style `<media-container>` yourself. See [Layout and fullscreen](#layout-and-fullscreen) for the complete layout example.

## Inside vs. outside the container

[`<video-player>`](https://videojs.org/docs/framework/html/reference/components/player) gives components access to state and actions. `<media-container>` layers on physical behaviors — fullscreen, activity detection, and gesture handling. Components work in both places; the container just adds those extras.

```html
<video-player>
  <media-container>
    <video src="video.mp4"></video>
    <media-controls><media-controls-content>...</media-controls-content></media-controls>  <!-- fullscreen, activity detection, gestures -->
  </media-container>

  <media-transcript></media-transcript>     <!-- state & actions, but no container behaviors -->
  <playlist-sidebar></playlist-sidebar>     <!-- state & actions, but no container behaviors -->
</video-player>
```

A play button outside the container still reads playback state and can toggle play/pause — it just won’t go fullscreen with the player or respond to the container’s idle state.

---

HTML documentation: https://videojs.org/docs/framework/html/llms.txt
All documentation: https://videojs.org/llms.txt
