LEARNING OBJECTIVES โต
- Understand the historical evolution and capitalization nuances across vendor prefixes (
webkit,moz,ms). - Handle iOS Safari limitations where fullscreen is restricted exclusively to
<video>elements viawebkitEnterFullscreen(). - Normalize cross-browser event names (
webkitfullscreenchange,mozfullscreenchange,MSFullscreenChange). - Build a zero-dependency, production-grade TypeScript/JavaScript Fullscreen adapter wrapper.
๐ The Mental Model & Story (Intuitive Foundation)
Imagine traveling across Europe in an electric car before universal charging standards were established.
In Germany, the charging stations used a 7-pin connector with a blue plug. In France, they used a 5-pin connector with a red lever. In Italy, they used a 3-pin connector with an inverted latch. If you didn't carry a universal adapter kit in your trunk, your car would be stranded at the border.
THE VENDOR PREFIX ADAPTER MATRIX
+-------------------------------------------------------------------------------+
| UNIFIED API CALL: `fullscreenAdapter.request(element)` |
+-------------------------------------------------------------------------------+
|
+-------------------------------+-------------------------------+
| | |
v v v
[Modern Standard] [Legacy WebKit/Blink] [Legacy Mozilla Gecko]
element.requestFullscreen() element.webkitRequestFullscreen() element.mozRequestFullScreen()
| | |
+-------------------------------+-------------------------------+
|
+-------------------------------+-------------------------------+
| | |
v v v
[Legacy Microsoft / IE] [iOS Safari <video>] [Fallback Mode]
element.msRequestFullscreen() video.webkitEnterFullscreen() CSS Pseudo-Fullscreen
The Fullscreen API underwent significant evolution before being standardized by the WHATWG. Older Safari releases, legacy Android WebViews, older Firefox builds, and Internet Explorer 11 all implemented their own proprietary method names and capitalization quirks (such as Mozilla's capital 'S' in mozRequestFullScreen).
A robust web application must implement an adapter layer that unifies these variants into a single, reliable API interface.
Technical Deep Dive & Specifications
The Vendor Prefix Taxonomy
The following matrix documents the complete historical taxonomy of Fullscreen methods, properties, and events:
+--------------------------------------------------------------------------------------------------------+
| CROSS-BROWSER VENDOR MATRIX |
+---------------------+-------------------------+------------------------+-------------------------------+
| Specification | Request Method | Exit Method | Active Element Property |
+---------------------+-------------------------+------------------------+-------------------------------+
| **WHATWG Standard** | `requestFullscreen()` | `exitFullscreen()` | `document.fullscreenElement` |
| **WebKit (Safari)** | `webkitRequestFullscreen()`| `webkitExitFullscreen()`| `document.webkitFullscreenElement`|
| **Gecko (Firefox)** | `mozRequestFullScreen()`| `mozCancelFullScreen()`| `document.mozFullScreenElement`|
| **Trident (IE/Edge)**| `msRequestFullscreen()`| `msExitFullscreen()` | `document.msFullscreenElement`|
+---------------------+-------------------------+------------------------+-------------------------------+
[!CAUTION] Notice the Capitalization Quirk in Mozilla:
Standard:requestFullscreen(lowercase 's')
WebKit:webkitRequestFullscreen(lowercase 's')
Gecko:mozRequestFullScreen(Uppercase 'S' inScreen!)
Gecko Exit:mozCancelFullScreen(Cancelinstead ofExit!)
The iOS Safari Special Case
On Apple iOS (iPhones), Apple restricts arbitrary DOM elements (such as <div> or <canvas>) from entering native OS fullscreen mode to protect the mobile Safari navigation gesture model.
However, HTML5 <video> elements on iOS support a proprietary WebKit media method:
const video = document.querySelector('video');
if (video.webkitEnterFullscreen) {
// Native iOS full-screen video player overlay
video.webkitEnterFullscreen();
}
+-------------------------------------------------------------------------------+
| SAFARI PLATFORM BEHAVIOR |
+-----------------------+-------------------------------------------------------+
| Platform | Fullscreen Capabilities |
+-----------------------+-------------------------------------------------------+
| **macOS Safari 16.4+**| Full standard WHATWG Fullscreen API on any DOM element|
| **iPadOS Safari 13+** | Supports standard `requestFullscreen()` on `<div>` |
| **iOS iPhone Safari** | โ Blocked on `<div>` / `<canvas>` |
| | โ
Supported on `<video>` via `webkitEnterFullscreen` |
+-----------------------+-------------------------------------------------------+
Normalizing Fullscreen Lifecycle Events
To ensure event handlers fire reliably across all legacy rendering engines, your application should bind all vendor-prefixed event strings:
const FULLSCREEN_EVENTS = [
'fullscreenchange',
'webkitfullscreenchange',
'mozfullscreenchange',
'MSFullscreenChange'
];
FULLSCREEN_EVENTS.forEach(eventName => {
document.addEventListener(eventName, onFullscreenStateChange, false);
});
๐ป Interactive Code Playground
Starter Code
Line-by-Line Code Breakdown
- Line 124โ182 (
class FullscreenAdapter): Implements an enterprise helper encapsulating standard and vendor-prefixed methods (requestFullscreen,webkitRequestFullscreen,mozRequestFullScreen,msRequestFullscreen). - Line 137โ146 (
getActiveElement): Normalizes the active element property check acrossdocument.fullscreenElement,document.webkitFullscreenElement,document.mozFullScreenElement, anddocument.msFullscreenElement. - Line 160โ168 (
exit): Normalizes document-level exit methods, correctly accounting for Gecko's historicalmozCancelFullScreen(). - Line 170โ178 (
bindChange): Binds all legacy and standard change events to guarantee execution across older browsers.
Expected Browser Render Output
- The table generates a live audit of your browser engine: modern Chrome and Edge show standard
requestFullscreenandwebkitRequestFullscreenas available. - Clicking "Toggle Fullscreen via Adapter" smoothly promotes the card using the highest-priority supported API.
- The adapter log streams all transition timestamps seamlessly.
๐๏ธ Hands-On Exercise
๐ฏ The Challenge: Author an Enterprise-Grade Cross-Browser Fullscreen Adapter
Instructions:
- Write a standalone utility function
toggleElementFullscreen(targetEl)that:- Evaluates standard and prefixed APIs.
- Gracefully handles iOS Safari video elements via
.webkitEnterFullscreen(). - Returns a Promise resolving to a boolean indicating whether the element is now fullscreen (
true) or windowed (false).
- Attach this utility to a simulated video player container.
- Add a fallback notification if the client platform is iOS and the target is a non-video element.
๐ Starter Code Sandbox
โ ๏ธ Common Pitfalls
- Misspelling Gecko's
mozRequestFullScreen: Note the capital'S'inScreenfor Mozilla. WritingmozRequestFullscreenwill fail silently asundefined. - Assuming iOS Safari Supports Fullscreen
<div>s: Testing only on desktop Chrome will hide the fact that iPhones reject<div>.requestFullscreen(). Always design a graceful CSS modal fallback for iPhone users. - Using Legacy MS Events Without Vendor Prefix: Internet Explorer 11 requires
MSFullscreenChangewith an uppercaseMS.
๐ก Pro Tips
- Implement Fallback CSS Pseudo-Fullscreen: When
FullscreenAdapter.isSupported()returns false (e.g. iPhone Safari), apply a CSS class.pseudo-fullscreen { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 999999; }to simulate fullscreen within the browser tab. - Adopt Modern Standards First: Always check standard
requestFullscreenas the first branch in your conditional chain, falling back to prefixes only if the standard method is undefined.
๐ Key Takeaways
- Older browsers required vendor prefixes: WebKit (
webkit), Mozilla (moz), and Microsoft (ms). - Mozilla Gecko used
mozRequestFullScreen(capital 'S') andmozCancelFullScreen(Cancel instead of Exit). - iOS Safari on iPhones only supports fullscreen on
<video>elements viawebkitEnterFullscreen(). - Normalizing event listeners requires binding
fullscreenchange,webkitfullscreenchange,mozfullscreenchange, andMSFullscreenChange. - Wrapping API calls in a unified TypeScript/ES6 adapter ensures bulletproof cross-device execution.
- --