Testing

Pointer Lock API: Browser Support, Features, Limitations

The Pointer Lock API works in Chrome 22+, Edge 13+, Firefox 50+, Safari 10.1+, and Opera 15+. iOS, Samsung Internet, and IE do not support it. Learn the API.

Author

Prince Dewani

May 1, 2026

The Pointer Lock API is a W3C JavaScript API that locks the cursor to one element, hides it, and reports raw mouse movement deltas. It works in Chrome 22+, Edge 13+, Firefox 50+, Safari 10.1+ on macOS, and Opera 15+, while Safari on iOS, Chrome for Android, Samsung Internet, and Internet Explorer do not support it.

This guide covers what the Pointer Lock API is, the browsers that support it, the key features, the mobile gap, and the known issues.

What is the Pointer Lock API?

The Pointer Lock API is a W3C JavaScript API that locks the mouse pointer to a target element through Element.requestPointerLock and reports cursor movement as movementX and movementY deltas on every MouseEvent. The cursor is hidden and stops at no screen boundary, so first-person games and 3D apps get unbounded raw input.

Which browsers does the Pointer Lock API support?

The Pointer Lock API works in Chrome 22+, Edge 13+, Firefox 50+, Safari 10.1+ on macOS, and Opera 15+ on desktop, while every iOS browser, Samsung Internet, Chrome for Android, and Internet Explorer leave it out.

Loading browser compatibility data...

Pointer Lock API compatibility in Chrome

Chrome supports the Pointer Lock API from Chrome 22 on Windows, macOS, Linux, and ChromeOS. Chrome 16 to 21 had it disabled by default behind a chrome://flags entry. Chrome 4 to 15 did not support it. Chrome for Android does not expose pointer lock in any version, since touch-first devices have no system cursor to lock.

Pointer Lock API compatibility in Edge

Microsoft Edge supports the Pointer Lock API from Edge 13 on Windows. The Chromium-based Edge 79 and newer ships it by default on Windows, macOS, and Linux. Edge 12 did not support pointer lock. Edge on Android does not expose the API, since the mobile build inherits the Chromium-on-Android behavior.

Pointer Lock API compatibility in Firefox

Firefox supports the Pointer Lock API from Firefox 50 on Windows, macOS, and Linux, with full unprefixed support and no flag. Firefox 14 to 49 shipped a moz-prefixed mozRequestPointerLock and required a fullscreen element first. Firefox 2 to 13 did not support it. Firefox for Android exposes the API only when a Bluetooth or USB OTG mouse is paired.

Pointer Lock API compatibility in Safari

Safari supports the Pointer Lock API from Safari 10.1 on macOS. Safari 3.1 to 10 did not support it. Safari on iOS and iPadOS does not support pointer lock in any version, including iOS 26 and iPadOS 26, since Apple WebKit has not enabled the feature on touch-first devices. Safari on visionOS also lacks the API.

Pointer Lock API compatibility in Opera

Opera supports the Pointer Lock API from Opera 15 on Windows, macOS, and Linux, the version where Opera switched to the Blink engine. Opera 9 to 12.1 did not support it. Opera Mini does not support pointer lock. Opera Mobile on Android also does not expose the API.

Pointer Lock API compatibility in Samsung Internet

Samsung Internet does not support the Pointer Lock API in any version on Galaxy phones or tablets. The Samsung Internet engine is Chromium-based, but the team has not turned on pointer lock on Android because mobile screens have no default mouse pointer. There is no flag inside the app that turns it on.

Pointer Lock API compatibility in Android Browser

The legacy stock Android Browser, Chrome for Android, Edge on Android, and Opera Mobile do not support the Pointer Lock API. Mobile Chromium builds disable the feature on touch-only devices. Firefox for Android is the only Android browser that ships pointer lock, and it only fires when a paired Bluetooth or USB OTG mouse is connected.

Pointer Lock API compatibility in Internet Explorer

Internet Explorer does not support the Pointer Lock API in any version, including Internet Explorer 11. The Trident engine never added the raw mouse delta plumbing the spec needs. Microsoft has retired Internet Explorer, so move pointer-locked games and 3D apps to Chromium-based Edge, Chrome, or Firefox for any new work.

Note

Note: The Pointer Lock API breaks across Safari on iOS, Samsung Internet, and Chrome for Android. Test it on real browsers and OS with TestMu AI. Try TestMu AI free!

What are the key features of the Pointer Lock API?

The Pointer Lock API is a small surface that pairs an entry method with movement deltas, lock-state events, and a fullscreen-friendly exit gesture. Every feature is exposed off Element, Document, and MouseEvent.

  • Element.requestPointerLock(options): Locks the cursor to the target element and hides it. Returns a Promise in modern browsers and accepts an unadjustedMovement option to skip OS-level mouse acceleration.
  • Document.exitPointerLock: Releases the lock and shows the cursor again. The Escape key triggers the same path automatically through the browser.
  • Document.pointerLockElement: Returns the element that currently owns the lock, or null when no lock is active. Pages read this to gate game-loop input.
  • MouseEvent.movementX and movementY: Carry the cursor delta since the previous event. clientX, clientY, screenX, and screenY freeze while the lock is active.
  • pointerlockchange event: Fires on Document when the lock state changes. Use it to start, pause, and resume a render loop.
  • pointerlockerror event: Fires on Document when requestPointerLock fails. Common causes are a missing user gesture, an iframe sandbox flag, or a competing lock on another element.
  • unadjustedMovement option: Returns OS-untouched delta values for raw input. Chrome and Edge support it; Firefox and Safari fall back to the OS-adjusted delta.
  • allow-pointer-lock sandbox token: An iframe must carry this sandbox token before requestPointerLock works. The parent page can scope the permission per frame.

What are the use cases of the Pointer Lock API?

The Pointer Lock API is built for any UI that wants raw, unbounded mouse motion without a visible cursor. The strongest fit is interactive 3D, but it carries any drag-rotate or scrub interaction that should not stop at the screen edge.

  • First-person and third-person browser games: FPS, racing, and flight sims use pointer lock to capture mouse-look without the cursor wandering off the canvas. Engines like Three.js ship a PointerLockControls helper that wraps the API.
  • 3D modeling and CAD tools on the web: Browser-based modelers map orbit, pan, and zoom to mouse drag. Pointer lock removes the screen-edge ceiling so the artist can rotate forever.
  • Map and satellite-imagery viewers: Pan and tilt over a globe stays smooth when the cursor cannot fall off the canvas. Cinematic camera moves on web globes use pointer-lock-style behavior.
  • Real-time strategy and city-builder games: RTS panning needs unlimited drag distance. Pointer lock turns a one-screen mouse pad into an infinite scroll surface.
  • Drawing and pixel-art tools: Tablet-emulating brushes can read raw delta to apply pressure-curve scaling. The hidden cursor keeps the canvas clean during a stroke.

Does the Pointer Lock API work on mobile browsers?

The Pointer Lock API does not work on iOS, iPadOS, or any Chromium mobile browser, and only Firefox for Android exposes it when a Bluetooth or USB mouse is paired. Mobile pages that need camera or pan control should fall back to Pointer Events or Touch Events instead.

Try the feature-detection snippet in the next section on a phone and the console will print "Pointer Lock API is not supported in this browser" on every Chromium-based mobile build.

  • Safari on iOS and iPadOS: No support in any version, including iOS 26 and iPadOS 26. Apple WebKit has not enabled the spec on iOS, and a paired Bluetooth mouse on iPad still cannot trigger pointer lock from a web page.
  • Chrome for Android: Does not support pointer lock. The Chromium feature is off in mobile builds because phones have no system mouse cursor by default.
  • Samsung Internet: Same Chromium base as Chrome for Android, so pointer lock is also disabled. Samsung One UI mouse mode does not unlock it for the web layer.
  • Firefox for Android: Supports the API only when the user has paired a Bluetooth or USB OTG mouse. Without a system pointer, requestPointerLock rejects.
  • Recommended fallback: Use Pointer Events with setPointerCapture for drag, and Touch Events for one-finger pan and pinch. The same canvas can keep its desktop pointer-lock path on top.
...

What are the known issues with the Pointer Lock API?

Pointer lock has shipped on Chromium for over a decade, but the surface still has a few sharp corners around user gestures, iframes, exit shortcuts, and cross-engine drift on options. Test the lock path on every target browser before you ship.

Paste the snippet below into the DevTools console of Chrome, Edge, Firefox, or Safari on macOS. Click anywhere on the page once and the cursor should disappear, with movement deltas printing on each frame.

// Paste this into the DevTools console to feature-detect Pointer Lock and start a lock on click.
const target = document.body;

if ("requestPointerLock" in target) {
  console.log("Pointer Lock API is available.");

  target.addEventListener("click", async () => {
    try {
      const result = target.requestPointerLock({ unadjustedMovement: true });
      if (result && typeof result.then === "function") {
        await result;
      }
      console.log("Pointer is locked.");
    } catch (error) {
      console.log("Lock rejected:", error.name);
    }
  });

  document.addEventListener("pointerlockchange", () => {
    const locked = document.pointerLockElement === target;
    console.log(locked ? "Locked." : "Released.");
  });

  document.addEventListener("mousemove", (event) => {
    if (document.pointerLockElement === target) {
      console.log("dx", event.movementX, "dy", event.movementY);
    }
  });
} else {
  console.log("Pointer Lock API is not supported in this browser.");
}
  • requestPointerLock needs a user gesture: Calling it from a setTimeout, fetch callback, or page-load script throws a SecurityError. Always wire it to a click, keypress, or pointerdown listener.
  • Escape always exits: The browser unlocks the cursor on Escape, regardless of the page's preferred shortcut. Games cannot rebind Escape to anything else while pointer lock is active.
  • Sandboxed iframes block it by default: An iframe needs the allow-pointer-lock sandbox token, or the inner page sees a SecurityError. Cross-origin embeds in CodePen and JSFiddle previews often forget this.
  • unadjustedMovement support drifts across engines: Chrome and Edge honor unadjustedMovement, Firefox ignores it, and Safari treats it as undefined. Catch the rejection's NotSupportedError name and fall back to the OS-adjusted delta.
  • Promise vs callback shape varies: Modern Chrome, Edge, and Firefox return a Promise from requestPointerLock; older Chrome and current Safari fire pointerlockchange or pointerlockerror without a Promise. Wrap both paths in your own helper.
  • Re-locking after Escape needs a fresh gesture: Once the user hits Escape, the next requestPointerLock call must come from a brand-new click. Auto-re-locking on a timer fails on every browser.
  • Chrome rolled back the planned permission prompt: Chrome 131 shipped a pointer-lock permission, but Google reverted the change after experiments showed it confused users on legitimate sites. Pages do not need to call navigator.permissions.query for pointer lock today.

In my experience, the most surprising failure is the iframe sandbox token. A perfectly working pointer-lock demo embedded inside a CodePen or JSFiddle preview suddenly throws SecurityError, because the parent page sandboxes the frame without allow-pointer-lock. The fix is one attribute on the iframe, but the error message points at the wrong layer.

...

Citations

All Pointer Lock API version numbers and platform notes in this guide come from these primary sources:

Author

Prince Dewani is a Community Contributor at TestMu AI, where he manages content strategies around software testing, QA, and test automation. He is certified in Selenium, Cypress, Playwright, Appium, Automation Testing, and KaneAI. Prince has also presented academic research at the international conference PBCON-01. He further specializes in on-page SEO, bridging marketing with core testing technologies. On LinkedIn, he is followed by 4,300+ QA engineers, developers, DevOps experts, tech leaders, and AI-focused practitioners in the global testing community.

Open in ChatGPT Icon

Open in ChatGPT

Open in Claude Icon

Open in Claude

Open in Perplexity Icon

Open in Perplexity

Open in Grok Icon

Open in Grok

Open in Gemini AI Icon

Open in Gemini AI

Copied to Clipboard!
...

3000+ Browsers. One Platform.

See exactly how your site performs everywhere.

Try it free
...

Write Tests in Plain English with KaneAI

Create, debug, and evolve tests using natural language.

Try for free

Frequently asked questions

Did you find this page helpful?

More Related Hubs

TestMu AI forEnterprise

Get access to solutions built on Enterprise
grade security, privacy, & compliance

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests