webdevpuneet.com

Fullscreen API Toggle Button — Free requestFullscreen Demo

Fullscreen API Toggle Button · Buttons · Plain HTML, CSS & JS · Live preview

CategoryButtons

Copy & paste

Source Code

<section class="fsb-wrap">
  <span class="fsb-tag">fullscreen api · requestfullscreen</span>
  <h1>Fullscreen toggle</h1>
  <p id="fsbStatus">Click the button to request fullscreen for the panel below.</p>

  <div class="fsb-panel" id="fsbPanel">
    <button class="fsb-btn" id="fsbToggle">
      <span id="fsbIcon">⤢</span>
      <span id="fsbLabel">Enter fullscreen</span>
    </button>
    <div class="fsb-content">
      <h2>Demo panel</h2>
      <p>This box becomes the fullscreen element when toggled. Press <kbd>Esc</kbd> to exit — the button updates automatically because it listens for the real <code>fullscreenchange</code> event, not just its own click.</p>
    </div>
  </div>

  <p class="fsb-note" id="fsbNote">If fullscreen is disallowed here (common inside a sandboxed preview iframe without <code>allow="fullscreen"</code>), a manual "simulated fullscreen" mode takes over instead.</p>
</section>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Real requestFullscreen/exitFullscreen
Uses the actual browser Fullscreen API.
Event-driven state
fullscreenchange listener, not click-local assumptions.
Vendor-prefix resolvers
Covers webkit/ms variants briefly.
fullscreenEnabled check
Detects outright disallowed contexts upfront.
Try/catch on request
Catches NotAllowedError/SecurityError gracefully.
Simulated fallback mode
A CSS-only enlarged panel when real API is blocked.
Clear status messaging
Explains which mode is active and why.
Esc-safe
Correctly reflects exits triggered outside the button.

About this UI Snippet

Fullscreen API Toggle Button — State Driven by the Real Event, Not the Click

Screenshot of the Fullscreen API Toggle Button snippet rendered live

This snippet wraps the browser's real Fullscreen API — element.requestFullscreen() and document.exitFullscreen() — in a single toggle button, and gets the one detail most homemade fullscreen buttons miss: the button's icon and label are driven entirely by the fullscreenchange event, never by the click handler's own assumption of what just happened.

Why the click handler can't be the source of truth

A user can leave fullscreen in ways that never touch your button at all — pressing Esc, using browser chrome, or switching apps on some platforms. If a toggle button only flips its own local "am I fullscreen" flag inside the click handler, it goes stale the instant the user exits with Esc. This snippet instead listens for the real fullscreenchange event (plus its webkitfullscreenchange/msfullscreenchange cousins) and checks document.fullscreenElement directly every time it fires, so the icon and label are always correct regardless of how fullscreen was entered or exited.

Vendor-prefix handling, kept minimal

Evergreen Chrome, Firefox, and Edge support the unprefixed requestFullscreen/exitFullscreen/fullscreenElement/fullscreenEnabled surface, but Safari has historically shipped webkit-prefixed variants in some versions. Small resolver functions (fsRequest, fsExit, fsElement, fsEnabled) pick whichever method actually exists on the element or document, so the rest of the code never has to branch on browser.

The blocked case: sandboxed iframes

Fullscreen is a permission-gated feature. Inside a sandboxed preview <iframe> without allow="fullscreen" in its attributes, document.fullscreenEnabled reports false outright, or a call to requestFullscreen() rejects with NotAllowedError/SecurityError. Both paths are caught and routed into a simulated fullscreen mode: the panel gets a CSS class that visually enlarges and highlights it in place, the button still toggles correctly, and a note explains plainly why the real API isn't in use. The demo never sits inert.

One toggle button, two real states

Clicking the button when nothing is fullscreen tries the real API first; only on failure does it fall back to the simulated class. Clicking again while simulated simply removes that class — no dead ends, no silent no-ops. Pair this with a screen wake lock toggle for a media-player control cluster, or a network information badge for a broader "browser capability" dashboard.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA panel with a fullscreen toggle button renders.
  2. 2
    Click "Enter fullscreen"The panel requests real browser fullscreen.
  3. 3
    Press EscThe button label updates via the real fullscreenchange event.
  4. 4
    Try it in a restricted contextBlocked fullscreen falls back to a simulated in-page mode.
  5. 5
    Click to exitWorks identically whether real or simulated.
  6. 6
    Style the fullscreen stateTarget :fullscreen for layout changes when active.

Real-world uses

Common Use Cases

Video and media players
Toggle a player panel in and out of real fullscreen, pairing with a screen wake lock toggle so the display does not sleep during viewing.
Image and photo viewers
Enlarge a single image or a whole gallery view, with icon and label driven by the real fullscreenchange event instead of click-local assumptions.
Dashboard fullscreen
Fullscreen a chart or an uptime status page on a wall display, falling back to a simulated mode when fullscreen is blocked.
Presentation and kiosk panels
Run slide or demo panels kiosk-style, checking fullscreenEnabled up front so outright disallowed contexts are detected early.
Playgrounds and sandboxed embeds
Offer distraction-free fullscreen editing for code panes, and ship safely inside sandboxed iframes thanks to the honest fallback.
Related: Neumorphic Button
See the Neumorphic Button for a related buttons pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Because the icon and label are driven by the real fullscreenchange event listener, which checks document.fullscreenElement every time it fires — not by a local flag the click handler sets. Esc, browser chrome, and OS-level exits all fire this event just like a programmatic exitFullscreen() call, so the UI stays accurate no matter how fullscreen ends.

The snippet checks document.fullscreenEnabled before requesting, and also wraps the request call in a catch for NotAllowedError or SecurityError. Either path routes into a simulated fullscreen mode that visually enlarges the panel with CSS instead, with a status note explaining that the real API is unavailable — the button keeps working either way.

Some Safari versions historically required webkitRequestFullscreen/webkitExitFullscreen and webkitFullscreenElement. This snippet resolves whichever variant exists at runtime via small helper functions, so it works across the unprefixed and webkit-prefixed API without separate code paths elsewhere.

Yes — requestFullscreen() is called on whatever element reference you pass to fsRequest(). Point it at any container (a video element, a chart div, a whole app shell) and update the fullscreenchange check to compare against that same element.

Keep a ref to the target element, call the same requestFullscreen/exitFullscreen resolvers on it from an event handler, and register the fullscreenchange listener in a mount effect, removing it on unmount. Store the active/simulated state in component state and drive the icon/label from that, exactly as the vanilla version does from the DOM.