Add a picture-in-picture button to any video
Picture-in-picture lets a video float above every other window while you work. Browsers support it natively, but plenty of sites strip the button out of their player. A JustZix rule puts it back on every video.
The API in one line
Any <video> element with metadata loaded can be moved into a floating window with video.requestPictureInPicture(). It returns a promise, and the browser requires it to be triggered by a user gesture such as a click.
someVideo.requestPictureInPicture().catch(function (err) {
console.warn('PiP refused:', err.message);
});
That is the whole engine. The rest of this article wraps it in a button you can click on any page.
A floating PiP button
This rule injects a single button. Clicking it finds the largest playing video and pops it out. Picking the largest video avoids triggering on tiny background or ad clips.
(function () {
if (!document.pictureInPictureEnabled) { return; }
var btn = document.createElement('button');
btn.textContent = 'PiP';
btn.style.cssText = 'position:fixed;bottom:16px;right:16px;z-index:2147483647;'
+ 'background:#2563eb;color:#fff;border:0;border-radius:8px;'
+ 'padding:8px 14px;font:600 13px sans-serif;cursor:pointer;'
+ 'box-shadow:0 2px 8px rgba(0,0,0,.3)';
document.body.appendChild(btn);
function biggestVideo() {
var best = null, bestArea = 0;
document.querySelectorAll('video').forEach(function (v) {
var r = v.getBoundingClientRect();
var area = r.width * r.height;
if (area > bestArea && v.readyState > 0) {
best = v; bestArea = area;
}
});
return best;
}
btn.addEventListener('click', function () {
if (document.pictureInPictureElement) {
document.exitPictureInPicture();
return;
}
var v = biggestVideo();
if (!v) { return; }
v.requestPictureInPicture().catch(function (err) {
btn.textContent = 'No PiP';
setTimeout(function () { btn.textContent = 'PiP'; }, 1500);
});
});
})();
The same button toggles: if a video is already in PiP it calls exitPictureInPicture(). The readyState > 0 check skips videos that have not loaded metadata yet, since the API rejects those.
Double-click any video to pop it out
If you prefer no on-screen button, bind the action straight to the videos. This rule makes a double-click on the video itself toggle PiP.
document.addEventListener('dblclick', function (e) {
var v = e.target;
if (!v || v.tagName !== 'VIDEO') { return; }
if (!document.pictureInPictureEnabled) { return; }
e.preventDefault();
if (document.pictureInPictureElement === v) {
document.exitPictureInPicture();
} else {
v.requestPictureInPicture().catch(function () {});
}
}, true);
Because the listener uses capture, it runs before the site's own double-click handler, and preventDefault() stops the player from toggling fullscreen at the same time.
Reacting to PiP events
You can keep your UI in sync by listening for enterpictureinpicture and leavepictureinpicture on a video:
document.addEventListener('enterpictureinpicture', function (e) {
console.log('floating:', e.target.currentSrc);
}, true);
Tips for reliable behaviour
- PiP needs a secure context. It works on
httpspages and rejects on plainhttp. - If a site sets
disablePictureInPictureon the element, clear it first withvideo.disablePictureInPicture = false. - Some single-page sites swap the video element on navigation, so keep the button rule active site-wide rather than per page.
Grab a packaged version from our ready-made examples or download JustZix to add it yourself. To stop videos from auto-playing in the first place, read stop video and audio autoplay.
Rate this post
No ratings yet — be the first.