Advanced

Fullscreen

Deep dive into fullscreen behavior, popover portaling, and mobile quirks.

How it works

ytcn calls containerRef.current.requestFullscreen() on the outermost player div — not the iframe. This means all custom controls, popovers, and overlays remain visible inside the fullscreen element.

Popover portaling

Radix UI popovers portal to document.body by default. In fullscreen, document.body is outside the fullscreen element and invisible. ytcn solves this by passing container={containerRef.current} to every Popover.

popover-portaling.tsx
<Popover>
  <PopoverTrigger asChild>
    <button>Speed</button>
  </PopoverTrigger>
  <PopoverContent
    // Portal INTO the player container — visible in fullscreen
    container={containerRef.current}
    side="top"
    align="end"
  >
    {/* Speed options */}
  </PopoverContent>
</Popover>

Don't remove the container prop

If you remove the container prop from any Popover, the speed picker (and any future popovers) will be invisible in fullscreen mode.

Idle controls in fullscreen

In fullscreen, controls auto-hide after 3 seconds of mouse inactivity via the useIdleControls hook. The cursor is also hidden using cursor-none. Both reset immediately on mouse movement.

Mobile behavior

PlatformBehavior
iOS SafariFullscreen opens native player — custom controls not visible
Android ChromeFullscreen API works — custom controls visible
Android FirefoxFullscreen API works — custom controls visible