The Picture-in-Picture (PiP) component provides an interface to both classic video Picture-in-Picture and Document Picture-in-Picture APIs. It enables your Progressive Web App to display content in a floating window that stays on top of other windows, allowing users to multitask while keeping your content visible.
This component is particularly useful for:
Video players and streaming applications
Video conferencing and calls
Live sports or event streaming
Tutorial and educational content
Dashboard monitoring and live data
Multi-window workflows
Browser Support
Classic Picture-in-Picture (Video):
Supported in Chrome, Edge, Safari, and Firefox
Works with <video> elements
Document Picture-in-Picture:
Supported in Chrome 116+ and Edge 116+
Can display any DOM content (not just video)
Currently experimental in other browsers
The component automatically falls back to classic PiP for video elements when Document PiP is not available.
Usage
Basic Video Picture-in-Picture
Video Player with PiP Controls
Document PiP (Any Content)
Video Conference with PiP
Live Stream Monitor
Music Player with Lyrics
Parameters
None
Actions
toggle
Toggles Picture-in-Picture mode. If not currently in PiP, it enters PiP mode. If already in PiP, it exits.
The action will:
Check if the floating target element is specified
For <video> elements: Use classic Video PiP API
For other elements: Use Document PiP API (where supported)
Automatically restore the element to its original position when exiting
Targets
floating
Required. The element to display in the Picture-in-Picture window.
For video elements: Uses classic Video PiP
For other elements: Uses Document PiP (Chromium browsers only)
container
Required. The parent container where the floating element should be restored when exiting PiP.
The component uses this target to remember where to put the element back after PiP closes.
Events
pwa--picture-in-picture:enter
Dispatched when the element successfully enters Picture-in-Picture mode.
No payload
Example:
pwa--picture-in-picture:exit
Dispatched when the Picture-in-Picture session ends.
No payload
This event fires when:
User closes the PiP window
toggle() action is called while in PiP mode
Browser automatically closes PiP
Example:
pwa--picture-in-picture:unsupported
Dispatched when Picture-in-Picture is not available.
No payload
Reasons for this event:
Browser doesn't support PiP
Feature is disabled by user/browser policy
Platform restrictions (e.g., trying Document PiP on unsupported browser)
Example:
pwa--picture-in-picture:error
Dispatched when entering or exiting PiP fails.
Payload: Error details
Example:
Best Practices
Provide clear controls: Make it obvious how to enter and exit PiP mode
Preserve state: Ensure playback state is maintained when entering/exiting PiP
Responsive design: PiP windows are typically small, design accordingly
Handle errors gracefully: Always listen for unsupported and error events
User interaction required: PiP can only be triggered by user actions
Test on devices: Behavior varies across browsers and platforms
Provide fallbacks: Not all browsers support Document PiP
Classic vs Document PiP
Feature
Classic PiP
Document PiP
Content
<video> only
Any DOM elements
Browser Support
Wide (all modern browsers)
Chrome/Edge 116+
Use Cases
Video streaming
Dashboards, widgets, any content
Styling
Limited
Full CSS control
Interactivity
Video controls only
Full DOM interaction
Browser-Specific Behavior
Chrome/Edge
Full support for both classic and Document PiP
Document PiP available from version 116+
Provides native PiP controls
Safari
Classic PiP supported for video
No Document PiP support
iOS Safari has platform-specific PiP UI
Firefox
Classic PiP supported
No Document PiP support yet
Provides built-in PiP button for videos
Styling PiP Content
When using Document PiP, you can style the floating content:
document.addEventListener('pwa--picture-in-picture:exit', () => {
console.log('Exited PiP mode');
// Update UI
document.querySelector('.pip-button').textContent = 'Enter PiP';
// The element is automatically restored to its container
});
document.addEventListener('pwa--picture-in-picture:unsupported', () => {
console.warn('PiP not supported');
// Hide PiP button
document.querySelector('.pip-button').style.display = 'none';
// Show message
alert('Picture-in-Picture is not supported on this device');
});