2 avril 2025
Document Picture-in-Picture, le PiP pour n’importe quel contenu HTML

7 minutes de lecture

Le mode Picture-in-Picture est surtout utilisé pour détacher un lecteur vidéo dans une fenêtre flottante toujours visible et au dessus, tout en continuant à naviguer sur une page.

Mais c’est d’une autre API similaire que je souhaite parler dans cet article : L'API Document Picture-in-Picture (PiP).
Elle pousse cette idée de fenêtre flottante un peu plus loin. Au lieu de se limiter aux vidéos, elle permet d’afficher n’importe quel document HTML dans une fenêtre PiP. Elle permet de créer des expériences utilisateur innovantes et de nouvelles façons de concevoir des interfaces.
Dans cet article, nous verrons comment utiliser cette API avant d’explorer des cas d’usage innovants qui tirent parti de son potentiel.
Cette API n’est prise en charge que par Chrome, à partir de la version 116. Si besoin il existe un flag pour activer/désactiver cette fonctionnalité chrome://flags/#document-picture-in-picture-api
.
Fonctionnement de l'API
L’API repose sur un objet global, documentPictureInPicture
, qui offre plusieurs points d’entrée pour interagir avec une fenêtre Picture-in-Picture dédiée à du contenu HTML quelconque. Voici les principales caractéristiques :
Propriété principale
documentPictureInPicture.window
Cette propriété renvoie la fenêtre PiP active si elle existe, sinon elle retourne null
. Elle permet ainsi d’accéder directement au contenu de la fenêtre pour, par exemple, interagir avec des éléments ou modifier son apparence.
Méthode d’ouverture d’une fenêtre Picture-in-Picture
documentPictureInPicture.requestWindow(options)
Cette méthode est au cœur de l’API. Elle ouvre une nouvelle fenêtre PiP et retourne une promesse qui se résout en un objet représentant cette fenêtre.
L’objet options
peut inclure plusieurs paramètres pour personnaliser la fenêtre :
width
etheight
: Ils définissent la taille initiale de la fenêtre PiP.disallowReturnToOpener
: En mettant cette option àtrue
, vous masquez le bouton permettant de revenir à l’onglet d’origine. Sa valeur par défaut estfalse
.preferInitialWindowPlacement
: Si défini surtrue
, la fenêtre s’ouvrira dans sa position et taille par défaut, sans reprendre la dernière configuration utilisée.
L’appel doit impérativement être initié suite à une interaction de l’utilisateur (clic, touche, etc.). Sinon, la promesse est rejetée.
Une fois une fenêtre PiP instanciée, vous pouvez la manipuler comme n'importe quel autre objet window
.
Exemple d’utilisation en JavaScript
Avant toute chose, étant donné que l'API n'est pas supportée par tous les navigateurs, il est nécessaire de vérifier si elle est supportée avant de l'utiliser.
if ('documentPictureInPicture' in window) {
// API is supported
}
Maintenant qu'on sait que l'API est supportée, pour afficher du contenu HTML dans une fenêtre PiP, il suffit de récupérer le contenu HTML et de l'ajouter à la fenêtre PiP.
pipButton.addEventListener("click", async () => {
const myContent = document.querySelector("#content");
const pipWindow = await documentPictureInPicture.requestWindow({
width: 500,
height: 500,
});
pipWindow.document.body.append(myContent);
});
Au click de l'utilisateur, une fenêtre flottante sera visible (de taille 500px x 500px) et contiendra le contenu HTML de l'élément #content
.
A la création de la fenêtre, le document PiP de cette dernière sera vide. Il faudra donc évidemment ajouter votre contenu HTML comme nous l'avons fait mais également, si besoin, ajouter du style (même chose pour les évènements, il faudra les ajouter sur la nouvelle fenêtre PiP).
Le plus simple reste de copier entièrement le style du document d'origine. Pour cela, on peut utiliser la fonction suivante :
function copyStyles(pipWindow) {
[...document.styleSheets].forEach((styleSheet) => {
try {
const cssRules = [...styleSheet.cssRules]
.map((rule) => rule.cssText)
.join('');
const style = document.createElement('style');
style.textContent = cssRules;
pipWindow.document.head.appendChild(style);
} catch (e) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.type = styleSheet.type;
link.media = styleSheet.media.mediaText;
link.href = styleSheet.href || '';
pipWindow.document.head.appendChild(link);
}
});
}
Pour copier toutes les feuilles de style CSS depuis la fenêtre d’origine, il faut parcourir manuellement les styleSheets liées ou intégrées dans le document, puis les ajouter à la fenêtre Picture-in-Picture. Attention, cette copie ne se fait qu’une seule fois, les styles ne seront pas mis à jour automatiquement par la suite.
La méthode copyStyleSheets
était supportée par Chrome dans une précédente version de la spécification de l'API mais a été supprimée.
Et voilà, nous avons maintenant une fenêtre PiP qui affiche du contenu HTML, et qui est stylée comme le reste du document.

Bien sûr il est possible d’aller plus loin en personnalisant finement le fonctionnement et le contenu de la fenêtre Picture-in-Picture.
On peut écouter / détecter son ouverture, sa fermeture, interagir avec son contenu, réagir via des événements classiques d'un document HTML, etc.
Côté style, on peut également spécifier des règles de style qui ciblent uniquement la fenêtre PiP. Pratique pour isoler les règles de style spécifiques au document PiP sans polluer le document principal :
@media all and (display-mode: picture-in-picture) {
body {
background-color: #000;
color: #fff;
}
h1 {
font-size: 0.8em;
}
}
Évidemment, il existe un wrapper React pour cette API. Mais je souhaitais ici vous présenter l'API dans sa forme native.
Cas d’usage interfaces utilisateur
Dans cette section, j’ai rassemblé quelques cas d’usage concrets et visuels pour illustrer comment cette API peut améliorer l’expérience utilisateur, fluidifier certaines interactions, ou simplement offrir un gain de confort et de productivité.
L’un des usages les plus aboutis de l'API Document Picture-in-Picture à ma connaissance est sans doute celui de Google Meet.
Lorsqu’on détache une réunion via le mode PiP, on retrouve une interface complète et interactive dans une fenêtre indépendante. On peut voir les participants, activer/désactiver son micro, quitter la réunion, suivre une présentation, lever la main. Presque toutes les fonctionnalités essentielles d’un meeting sont disponibles dans cette version compacte.

C’est un excellent exemple de ce que permet cette API : rester actif dans une réunion tout en poursuivant une autre tâche, sans avoir besoin de jongler entre les onglets ou fenêtres. Cela rend l’expérience beaucoup plus fluide, surtout dans un contexte de multitâche.
À partir de là, on peut imaginer toutes sortes de déclinaisons d'usage dans des composants applicatifs.
Voici quelques autres cas d'utilisation concrets, illustrés par des captures, qui montrent comment cette API peut transformer l’interface utilisateur dans différents contextes.
Lecteur de média interactif
Ici, j'ai conçu un petit exemple d'un lecteur audio Soundcloud qui afficherait les commentaires des utilisateurs. Ainsi qu'un live Twitch où on pourrait commenter en live.
Éditeur de texte en ligne
Dans une application web de type éditeur de code avec preview, on pourrait afficher la preview dans une fenêtre flottante. Pour que les utilisateurs ayant deux écrans puissent profiter de l'interface d'édition en entier.
Ici j'ai repris un exemple disponible sur le site de Chrome For Developers.

Documentation en fenêtre flottante
Une documentation pourrait intégrer une fenêtre flottante afin d'avoir constamment à portée de main les informations importantes. Et éviter les aller-retour entre la documentation et le code.

Progression d'un build
Parfois, on peut avoir besoin de surveiller la progression d'un build, ou d'un processus quelconque qui peut prendre du temps.
Avec une fenêtre flottante, on peut garder un œil sur la progression de ce processus tout en continuant à travailler sur une autre tâche.

Limites de l'API
Bien que cette API soit très intéressante, elle présente tout de même quelques limites importantes de connaître.
Un support limité
D’abord, son support est aujourd’hui limité à Google Chrome et aux navigateurs basés sur Chromium.
Pas de navigation possible
Ensuite, il est important de noter que la fenêtre PiP ne permet ni navigation entre différentes pages, ni redirection. Il s’agit d’un document isolé, lié à l’environnement de la page principale. L’objectif est d'étendre un composant de votre page, pas de créer une nouvelle instance autonome de l'application.
Une seule fenêtre flottante par onglet
Pour des raisons évidentes le navigateur limite l'affichage à une seule fenêtre PiP à la fois (par onglet ouvert).
Gestion manuelle des styles et scripts
Enfin, le système de styles et de scripts dans la fenêtre PiP demande une gestion manuelle. Il n’y a pas de synchronisation automatique avec le document principal, ce qui peut représenter un effort supplémentaire de maintenance.
Si vous souhaitez tester rapidement des comportement Picture-in-Picture sur un site web. Je vous recommande cette extension Chrome qui permet d'activer le mode PiP sur n'importe quel élément d'une page web.
Conclusion
L'API Document Picture-in-Picture ouvre la voie à des interfaces flottantes plus interactives et utiles, bien au-delà de la simple vidéo. Malgré un support limité à Chrome pour l’instant,elle offre déjà de belles opportunités pour améliorer l’expérience utilisateur, notamment dans des contextes SaaS ou des outils de productivité. Une API à surveiller et à expérimenter dès aujourd’hui.