JavaScript Fullscreen API
Learn the JavaScript Fullscreen API: enter and exit fullscreen, handle fullscreenchange events, and fix common gotchas with working examples.
Introduction to the JavaScript Fullscreen API
The JavaScript Fullscreen API lets a web page ask the browser to display a single element — and only that element — using the entire screen, hiding the address bar, tabs, and the operating system's chrome. This is what powers the fullscreen button you see on video players, online games, presentation tools, and image galleries.
This chapter covers how to enter and exit fullscreen, how to react to fullscreen changes with events, the gotchas you will hit (the user-gesture requirement, the Promise it returns, and styling), and browser support. The key methods and properties are:
Element.requestFullscreen()— ask for an element to fill the screen. Returns a Promise.Document.exitFullscreen()— leave fullscreen and return to the normal page.document.fullscreenElement— the element currently shown fullscreen, ornullif none.document.fullscreenEnabled—trueif fullscreen is available and not blocked.fullscreenchange/fullscreenerrorevents — fire when the state changes or a request fails.
Enabling Fullscreen Mode in JavaScript
To enter fullscreen, call the requestFullscreen() method on any DOM element you want to enlarge — a video, a <div>, a <canvas>, even the whole document.documentElement.
Two rules matter from the start:
- A user gesture is required. Browsers only honour
requestFullscreen()when it runs inside a real interaction such as a click or key press. Calling it on page load or from a timer is silently rejected, so it is almost always called from inside an event handler. - It returns a Promise. The Promise resolves when fullscreen succeeds and rejects (with an error) if the browser refuses. Always attach a
.catch()so a refusal does not become an unhandled rejection.
<div id="main-content">
<button id="fs-btn">Go Fullscreen</button>
<div id="video-container">
<!-- Your content like a video or interactive media -->
</div>
</div>
<script>
const element = document.getElementById("video-container");
const btn = document.getElementById("fs-btn");
btn.addEventListener("click", function() {
if (document.fullscreenEnabled) {
element.requestFullscreen().catch(err => {
console.error(`Error attempting to enable fullscreen: ${err.message}`);
});
} else {
console.log("Fullscreen API is not supported in this browser.");
}
});
</script>This snippet triggers fullscreen for the video-container element when the button is clicked. The check on document.fullscreenEnabled guards against browsers (or embedded contexts such as a sandboxed <iframe>) where the feature is unavailable, and the .catch() reports any refusal instead of letting it fail silently.
Controlling navigation UI
requestFullscreen() accepts an optional options object. The navigationUI property hints whether the browser should keep its navigation controls (back button, URL bar) visible:
// "hide" → request a truly immersive, chrome-free view (default for most browsers)
// "show" → keep the browser's navigation UI on screen
// "auto" → let the browser decide
element.requestFullscreen({ navigationUI: "hide" });It is only a hint — the browser is free to ignore it — but it is useful for games and video where you want the most immersive view possible.
Exiting Fullscreen Mode
A page can only have one fullscreen element at a time, so you do not need to know which element is active to leave — document.exitFullscreen() always exits the current one and returns the page to its normal layout:
<div id="exit-button">
<button id="exit-btn">Exit Fullscreen</button>
</div>
<script>
document.getElementById("exit-btn").addEventListener("click", function() {
if (document.exitFullscreen) {
document.exitFullscreen();
}
});
</script>Here the user leaves fullscreen by clicking an Exit Fullscreen button. The check if (document.exitFullscreen) confirms the method exists before calling it. Note that the browser also lets the user exit at any time by pressing Esc — your code does not control that, which is exactly why you should listen for the fullscreenchange event rather than assume your button is the only way out.
Handling Fullscreen Changes with Events
The Fullscreen API fires events whenever the state changes, no matter how it changed — your button, the Esc key, or the browser itself. Listening for them is the reliable way to keep your UI in sync (for example, swapping an "enter" icon for an "exit" icon):
document.addEventListener("fullscreenchange", function(event) {
if (document.fullscreenElement) {
console.log("Entered fullscreen mode");
} else {
console.log("Exited fullscreen mode");
}
});This event listener logs messages to the console based on whether the document is in fullscreen mode or not, helping developers understand the state transitions. Additionally, you should handle the fullscreenerror event to catch cases where the browser denies the request (e.g., due to security restrictions or user cancellation):
document.addEventListener("fullscreenerror", function(event) {
console.error("Fullscreen request failed:", event.target.error);
});Here event.target is the element the request was made on; reading .error on it (or simply logging the event) tells you why the browser declined.
Now let's put it all together in a complete, working example:
A Full Example
<div id="main-content">
<button id="fs-btn">Go Fullscreen</button>
<div id="video-container" style="position: relative; height: 100vh; display: flex; align-items: center; justify-content: center;">
<div id="exit-button" style="display: none;">
<button id="exit-btn">Exit Fullscreen</button>
</div>
</div>
</div>
<script>
const element = document.getElementById("video-container");
const exitBtn = document.getElementById("exit-btn");
const exitButtonContainer = document.getElementById("exit-button");
document.getElementById("fs-btn").addEventListener("click", function() {
if (document.fullscreenEnabled) {
element.requestFullscreen().catch(err => {
console.error(`Error attempting to enable fullscreen: ${err.message}`);
});
}
});
exitBtn.addEventListener("click", function() {
if (document.exitFullscreen) {
document.exitFullscreen();
}
});
function updateButtonVisibility() {
exitButtonContainer.style.display = document.fullscreenElement ? "block" : "none";
}
document.addEventListener("fullscreenchange", updateButtonVisibility);
document.addEventListener("fullscreenerror", function(event) {
console.error("Fullscreen request failed:", event.target.error);
});
</script>Here is how each part works:
- The "Go Fullscreen" handler checks
document.fullscreenEnabledand then callselement.requestFullscreen()on the video container, catching any rejection. - The "Exit Fullscreen" handler calls
document.exitFullscreen()to return to the normal page. updateButtonVisibility()shows the exit button only while an element is actually fullscreen, readingdocument.fullscreenElement.- The
fullscreenchangelistener runsupdateButtonVisibility()on every state change — including when the user presses Esc — so the UI never gets out of sync, and thefullscreenerrorlistener reports a refused request.
Compatibility and Browser Support
The Fullscreen API is supported across all modern browsers — Chrome, Firefox, Safari, Opera, and Edge — using the standard, unprefixed methods. Older Safari (and very old Chrome/Edge) used the -webkit- prefix (webkitRequestFullscreen, webkitExitFullscreen). If you need to support those, fall back to the prefixed name:
function openFullscreen(element) {
if (element.requestFullscreen) {
return element.requestFullscreen();
}
if (element.webkitRequestFullscreen) { // older Safari
return element.webkitRequestFullscreen();
}
}
function closeFullscreen() {
if (document.exitFullscreen) {
return document.exitFullscreen();
}
if (document.webkitExitFullscreen) { // older Safari
return document.webkitExitFullscreen();
}
}For styling an element while it is fullscreen, use the CSS :fullscreen pseudo-class:
#video-container:fullscreen {
background-color: #000;
color: #fff;
padding: 20px;
}Common gotchas
- No user gesture, no fullscreen. Calling
requestFullscreen()outside a click or key handler is rejected. Trigger it from a real interaction. - Sandboxed iframes are blocked unless the iframe carries the
allow="fullscreen"attribute. - Handle the Promise rejection. A user can deny the request, or policy can block it — always add
.catch(). - Don't trust your own button alone. The Esc key exits fullscreen without touching your code, so rely on the
fullscreenchangeevent to update the UI.
Conclusion
The Fullscreen API gives you a clean, gesture-driven way to let a single element take over the screen for video, games, presentations, and galleries. Remember the essentials: request from a user gesture, handle the returned Promise, exit with document.exitFullscreen(), and keep your interface in sync by listening for the fullscreenchange event rather than assuming how the user left fullscreen.
To keep learning, explore browser events, DOM manipulation, and Promises, all of which the Fullscreen API builds on.