How to Handle Fullscreen Problems in Embedded Browser Games

Fullscreen in an embedded game fails for one of three reasons: the iframe was not given permission, the browser does not offer fullscreen for that kind of element, or the request did not come from a real click or tap. This guide shows each case with what we measured, then gives you a fallback that works when the browser has no fullscreen at all.
Case 1: The iframe has no permission
A frame from another site may only go fullscreen if the page that embeds it allows it. That is the allow="fullscreen" attribute (or the older allowfullscreen). We tested a cross-origin test frame with a button that called requestFullscreen():
| Iframe | Result after a click on the button inside the frame |
|---|---|
Without allow="fullscreen" | Failed: "Disallowed by permissions policy". document.fullscreenEnabled was false in the frame, and the console showed "Permissions policy violation: fullscreen is not allowed in this document." |
With allow="fullscreen" | Worked, and document.fullscreenEnabled was true |
MDN states the same rule for its legacy form: iframes opt in with the allowfullscreen attribute.
Fix: use the full embed code, which includes allow="fullscreen; autoplay; gamepad; pointer-lock" and allowfullscreen. The most common cause of a dead fullscreen button is a trimmed embed code.
Case 2: The request is not a user action
MDN notes that fullscreen requests need to be made from within an event handler, or they are denied. If you build your own fullscreen button, call requestFullscreen() directly in the click handler. Do not call it after a timer or a network request.
Case 3: The browser does not support it for this element
This is the case you cannot fix with an attribute. MDN's browser compatibility data for Element.requestFullscreen() records, for Safari on iOS and iPadOS:
- support from version 16.4, marked as a partial implementation;
- the note: "Only available on iPad, not on iPhone";
- a second note that it shows an overlay button that cannot be disabled, and swiping down exits fullscreen, which makes it unsuitable for some uses such as games.
So on an iPhone, a button that asks the page's frame to go fullscreen has nothing to call. The game may still offer its own fullscreen or "rotate" prompt. We cannot test iPhones here, so check this on a real device.
The fallback: a CSS "pretend fullscreen"
If native fullscreen is missing or fails, make the game fill the screen yourself. The wrapper becomes a fixed layer covering the viewport, with a visible exit button:
<div class="wrap" id="w">
<button class="exit" id="exit">Exit fullscreen</button>
<iframe src="https://playkovo.com/embed/block-bash" title="Block Bash"
allow="fullscreen; autoplay; gamepad; pointer-lock" allowfullscreen></iframe>
</div>
<button id="go">Fullscreen</button>
<style>
.wrap { position: relative; max-width: 960px; aspect-ratio: 16/9; margin: 0 auto; background: #000; }
.wrap iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.wrap.is-pseudo-fs { position: fixed; inset: 0; z-index: 2147483000; max-width: none; aspect-ratio: auto; width: 100%; height: 100dvh; }
.wrap .exit { display: none; position: absolute; top: 8px; right: 8px; z-index: 2; padding: 8px 12px; }
.wrap.is-pseudo-fs .exit { display: block; }
</style>
<script>
const w = document.getElementById("w");
function setPseudo(on) {
w.classList.toggle("is-pseudo-fs", on);
document.documentElement.style.overflow = on ? "hidden" : "";
}
go.onclick = async () => {
if (w.requestFullscreen) {
try { await w.requestFullscreen(); return; } catch (e) {}
}
setPseudo(true);
};
exit.onclick = () => setPseudo(false);
addEventListener("keydown", (e) => { if (e.key === "Escape") setPseudo(false); });
</script>Note that the script asks for fullscreen on the wrapper, not on the iframe, so your exit button and any overlays come with it, and falls back to the CSS layer when the call is missing or refused.
We tested this page in Chrome 155:
| Test | Result |
|---|---|
| Desktop 1280 by 720, native API available | Native fullscreen used; the wrapper measured 1280 by 720, the same as the viewport |
| Phone profile (Pixel 7) with the Fullscreen API removed to imitate an iPhone | Fallback used; the wrapper measured 412 by 839, the same as the viewport |
| Escape in fallback mode | Wrapper returned to its normal class |
That second test is a simulation. A real iPhone has its own browser chrome, safe-area insets and a keyboard-less gesture to leave, so test the fallback on a real device and add padding: env(safe-area-inset-*) if content hides behind the notch.
Mobile fullscreen tips
- Use
100dvh, not100vh. Mobile browsers have an address bar that changes the visible height.dvhfollows it. - Offer a visible exit. Do not rely on the user knowing a swipe or a key.
- Lock nothing. Do not call orientation locks you cannot undo. Many portrait games expect portrait, and landscape games work better rotated, so let the player rotate the phone.
- Hide only your own chrome. Games may show their own fullscreen button. If both appear, do not fight it. Offer yours only where the game has none.
A quick diagnosis
- Does the iframe carry
allow="fullscreen"? If not, add it. - Is your button calling
requestFullscreen()inside the click handler? - Is the device an iPhone? Use the CSS fallback.
- Does the console say "Permissions policy violation"? The embed code lost its
allowlist. - Does fullscreen work in the normal browser but not inside another app's built-in browser? We did not test in-app browsers, but they are a likely place for restrictions, so offer a link to open the page in the normal browser.
A game to test it on
Try it live · PlayKovo catalog
DesktopsupportedMobilesupportedA free, browser-based multiplayer dogfighter set in a Minecraft-inspired voxel world. Two teams, planes, tanks, and ships, one golden ring to fight over.
Related Posts

We Compared 20 Embeddable Games for Small Websites
We opened 20 games from PlayKovo's embed catalog in real Chrome, on desktop and with a phone profile, pressed play and recorded what loaded, what failed and how heavy each was. Here are the results, what the numbers do and do not tell you, and which games we would start with.

Should You Host HTML5 Games Yourself or Use a Game Distributor?
For most websites the answer is a distributor, and bandwidth is not the reason. Here is a neutral comparison of cost, updates, licensing, control and maintenance, with measured game sizes behind the cost arithmetic.

Which HTML5 Game Genres Work Best for Touchscreen Websites?
Genres that ask for one tap, one drag or one swipe suit phones; genres built on joysticks and several buttons suit them less. We classified the declared mobile controls of all 73 mobile-ready games in PlayKovo's feed and show the pattern by genre, with the limits of that method.