Chapter 55: Screen Orientation & Device APIs

Locking Screen Orientation

Control viewport rotation programmatically with `screen.orientation.lock()`, understand fullscreen prerequisites, and handle cross-browser security constraints.

LEARNING OBJECTIVES
  • Programmatically lock the display orientation using screen.orientation.lock() with specific lock types (landscape, portrait, any, natural).
  • Understand why calling lock() requires a Fullscreen API state or standalone PWA context.
  • Handle DOMException error types (NotSupportedError, SecurityError, AbortError) with asynchronous try...catch blocks.
  • Programmatically unlock orientation using screen.orientation.unlock() during cleanup routines.
🎬 INTERACTIVE VISUAL PIPELINE Core Architecture Simulation
🌐
1. Input
Directives & Tags
⚙️
2. Parse
Tokenizer & AST
🌳
3. Layout
Box Model & Flow
🎨
4. Render
GPU Paint & Composite
PHASE 1: INPUT & DIRECTIVES
Browser receives declarative markup stream, parsing tag tokens and initializing component state.

📖 The Mental Model & Story (Intuitive Foundation)

Imagine a passenger sitting on a high-speed train playing a flight simulator on their tablet. As the train sways around sharp mountain curves, the tablet's physical accelerometer thinks the device is rotating and continuously flips the game viewport upside down and sideways, breaking the flight controls.

                      +----------------------------------+
                      |       USER ENTERS FULLSCREEN     |
                      |  document.documentElement        |
                      |    .requestFullscreen()          |
                      +----------------------------------+
                                       │
                                       ▼
                      +----------------------------------+
                      |     REQUEST ORIENTATION LOCK     |
                      |  screen.orientation.lock(        |
                      |    'landscape-primary'           |
                      |  )                               |
                      +----------------------------------+
                                       │
                   ┌───────────────────┴───────────────────┐
                   ▼                                       ▼
        [ PROMISE RESOLVES ✅ ]                  [ PROMISE REJECTS ❌ ]
        - Hardware display is                   - Not in Fullscreen
          pinned to landscape                   - User denied permission
        - OS ignores physical tilts             - OS/Browser unsupported (iOS)

To prevent unwanted display rotation in games, video players, and VR experiences, browsers provide screen.orientation.lock(). However, because locking the entire screen orientation takes control away from the user, browsers enforce strict security boundaries: your web app can only lock the orientation if it has received user interaction and entered Fullscreen mode or is installed as a Progressive Web App (PWA).


Technical Deep Dive & Specifications

The lock() Method Signature & Parameters

The lock() method returns a standard JavaScript Promise that resolves with undefined when the lock is active or rejects with a DOMException if the lock fails:

screen.orientation.lock(orientationLockType: OrientationLockType): Promise<void>;
screen.orientation.unlock(): void;

type OrientationLockType = 
  | "any"                  // Unlocks any orientation (both portrait and landscape)
  | "natural"              // Natural hardware baseline (portrait on phones, landscape on PCs)
  | "landscape"            // Either landscape-primary or landscape-secondary
  | "portrait"             // Either portrait-primary or portrait-secondary
  | "portrait-primary"     // Upright portrait only
  | "portrait-secondary"   // Inverted portrait only
  | "landscape-primary"    // Sideways landscape only
  | "landscape-secondary"; // Inverted sideways landscape only

The Orientation Lock Type Hierarchy

                                  [ ANY ]
                    (Allows all 4 physical rotations)
                                     │
                 ┌───────────────────┴───────────────────┐
                 ▼                                       ▼
           [ PORTRAIT ]                            [ LANDSCAPE ]
        (0° or 180° only)                       (90° or 270° only)
           │          │                            │          │
     ┌─────┘          └─────┐                ┌─────┘          └─────┐
     ▼                      ▼                ▼                      ▼
[ portrait-primary ]  [ portrait-secondary ] [ landscape-primary ]  [ landscape-secondary ]
    (Upright)            (Inverted)              (Rotated 90°)          (Rotated 270°)

Security & Prerequisite Requirements Matrix

Why does screen.orientation.lock() fail? Browsers enforce three strict prerequisites:

Requirement Why It Is Mandated Result if Missing
Secure Context (HTTPS) Prevents man-in-the-middle scripts from hijacking display controls. Throws SecurityError
Fullscreen Mode or Installed PWA A standard web tab cannot hijack the entire OS screen unless the user agreed to full immersion. Throws NotSupportedError / SecurityError
Transient User Activation Must be triggered inside a click, tap, or touch event handler. Throws SecurityError

DOMException Error Handling Reference

try {
  await screen.orientation.lock('landscape');
} catch (error) {
  switch (error.name) {
    case 'NotSupportedError':
      console.warn('Orientation locking not supported on this device/browser.');
      break;
    case 'SecurityError':
      console.warn('Locked out: Must enter Fullscreen or run as installed PWA.');
      break;
    case 'AbortError':
      console.warn('Lock request was aborted by another concurrent orientation change.');
      break;
    default:
      console.error('Orientation lock failed:', error);
  }
}

💻 Interactive Code Playground

Starter Code

Line-by-Line Code Breakdown

  • Lines 134–146: Manages entering and exiting Fullscreen mode via document.documentElement.requestFullscreen(), fulfilling the mandatory browser prerequisite.
  • Lines 149–153: Evaluates feature detection for screen.orientation.lock to prevent fatal runtime errors on iOS Safari or legacy browsers.
  • Lines 155–158: Executes await screen.orientation.lock(lockMode) inside an asynchronous try...catch wrapper.
  • Lines 159–165: Catches specific DOMException types (SecurityError, NotSupportedError) and gives actionable diagnostic feedback.
  • Lines 174–180: Calls screen.orientation.unlock() to release hardware display constraints, restoring natural OS sensor responsiveness.

Expected Browser Render Output


SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
HTML STARSHIP CODE TERMINAL playground.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45°C
INSPECTING DOM: VALID
TAGS: SCANNING...
🔒 Screen Orientation Lock
Locking screen orientation requires Fullscreen mode on mobile web browsers.

[ Current: portrait-primary (0°) ]

[ 1️⃣ Enter Fullscreen Mode                                      ]
[ 🔒 Lock Landscape       ] [ 🔒 Lock Portrait                 ]
[ 🔒 Lock Landscape-Primary] [ 🔒 Lock Natural                  ]
[ 🔓 Unlock Orientation                                        ]

System ready. Enter fullscreen before locking.
[10:20:10 AM] ℹ️ Requesting lock("landscape")...
[10:20:10 AM] ❌ SecurityError: Must enter Fullscreen mode before locking orientation.

🏋️ Hands-On Exercise

🎯 The Challenge: Build an Auto-Locking Arcade Game Launcher

Instructions:

  1. Build an HTML page with a "Launch Arcade Mode" button.
  2. When the user clicks the button:
    • Request Fullscreen on the game canvas container.
    • Attempt to lock the orientation to 'landscape-primary'.
    • If lock() fails (e.g. on desktop or iOS), fall back gracefully by rendering an in-game UI notification asking the player to turn their device.
  3. When the user exits fullscreen (listens to fullscreenchange), automatically unlock the orientation via screen.orientation.unlock().

🏁 Starter Code Sandbox

SYS: ACTIVE
HULL: 98%
CORE: STABLE
NET: ONLINE
STARTER CODE SANDBOX exercise.html
LIVE RENDER & DIAGNOSTICS CORE TEMP: 45°C
INSPECTING DOM: VALID
TAGS: SCANNING...

⚠️ Common Pitfalls

  1. Invoking lock() Outside Fullscreen or PWA Mode: Calling screen.orientation.lock() on a standard un-fullscreened web page will trigger an unhandled Promise rejection with SecurityError or NotSupportedError.
  2. Forgetting iOS Safari Incompatibility: As of modern iOS versions, Apple WebKit does not implement screen.orientation.lock(). Never assume the promise exists without checking 'lock' in screen.orientation.
  3. Failing to Unlock on Exit: If you lock the screen inside an experience and forget to call unlock(), the user may remain trapped in landscape orientation even after closing your modal dialog.

💡 Pro Tips

  1. Declare Orientation in Web App Manifest: For Progressive Web Apps, you can declaratively enforce orientation without writing JavaScript by adding "orientation": "landscape" or "orientation": "portrait" inside your manifest.json.
  2. Handle Transient Abort Rejections: If a user violently flips their phone while lock() is executing, the browser may reject with an AbortError. Always wrap your lock() call in a resilient try...catch block.

📌 Key Takeaways

  • screen.orientation.lock() locks the browser display to a chosen orientation subtype (e.g. 'landscape', 'portrait-primary').
  • Programmatic locking strictly requires a Fullscreen state or an Installed PWA context.
  • screen.orientation.unlock() releases hardware display locking and restores normal accelerometer orientation tracking.
  • Always handle NotSupportedError, SecurityError, and AbortError DOMException rejections.
  • Always tie orientation unlocking to the fullscreenchange event.
  • --
⭐ LEARN: HTML 🌟 ⚔️ QUIZ BATTLE ARENA // ACTIVE
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 1 / 3

What is the required prerequisite for a regular mobile browser tab before calling screen.orientation.lock()?

Question 1 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 2 / 3

Which lock parameter value locks the screen into landscape mode while allowing the user to rotate between $90^\circ$ and $270^\circ$ sideways?

Question 2 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP
3x
STREAK!
BONUS ACTIVE
COMBO
? Question 3 / 3

What method should be called to restore the device to its normal free-rotating behavior?

Question 3 / 3 Topic: HTML Fundamentals
00:45 REMAINING
XP REWARD
+250 XP