Screen Orientation

W3C Working Draft

More details about this document
This version:
https://www.w3.org/TR/2023/WD-screen-orientation-20230809/
Latest published version:
https://www.w3.org/TR/screen-orientation/
Latest editor's draft:
https://w3c.github.io/screen-orientation/
History:
https://www.w3.org/standards/history/screen-orientation/
Commit history
Test suite:
https://wpt.live/screen-orientation/
Editor:
Marcos Cáceres (Apple Inc.)
Former editors:
Mounir Lamouri (Google Inc.)
Johanna Herman (Invited Expert)
Feedback:
GitHub w3c/screen-orientation (pull requests, new issue, open issues)
Browser support:
caniuse.com

Abstract

The Screen Orientation specification standardizes the types and angles for a device's screen orientation, and provides a means for locking and unlocking it. The API, defined by this specification, exposes the current type and angle of the device's screen orientation, and dispatches events when it changes. This enables web applications to programmatically adapt the user experience for multiple screen orientations, working alongside CSS. The API also allows for the screen orientation to be locked under certain preconditions. This is particularly useful for applications such as computer games, where users physically rotate the device, but the screen orientation itself should not change.

Status of This Document

This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This document is a work in progress.

This document was published by the Web Applications Working Group as a Working Draft using the Recommendation track.

Publication as a Working Draft does not imply endorsement by W3C and its Members.

This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 12 June 2023 W3C Process Document.

1. Example of usage

This section is non-normative.

In this example clicking the "Lock" button requests to go into fullscreen and then locks the screen to the opposite orientation. clicking the "unlock" button unlocks the screen.

Example 1: Locking to a specific orientation and unlocking
<script>
function updateLockButton() {
  const lockButton = document.getElementById("button");
  const newOrientation = getOppositeOrientation();
  lockButton.textContent = `Lock to ${newOrientation}`;
}

function getOppositeOrientation() {
  return screen
    .orientation
    .type
    .startsWith("portrait") ? "landscape" : "portrait";
}

async function rotate(lockButton) {
  if (!document.fullscreenElement) {
    await document.documentElement.requestFullscreen();
  }
  const newOrientation = getOppositeOrientation();
  await screen.orientation.lock(newOrientation);
  updateLockButton(lockButton);
}

screen.orientation.addEventListener("change", updateLockButton);

window.addEventListener("load", updateLockButton);
</script>

<button onclick="rotate(this)" id="button">
  Lock to...
</button>
<button onclick="screen.orientation.unlock()">
  Unlock
</button>

2. Concepts

To lock the screen orientation to an OrientationLockType orientation means that the screen can only be rotated by the user to a specific screen orientation - possibly at the exclusion of other orientations. The possible orientations to which the screen can be rotated is determined by the user agent, a user preference, the operating system's conventions, or the screen itself. For example, locking the orientation to landscape means that the screen can be rotated by the user to landscape-primary and maybe landscape-secondary if the system allows it, but won't change the orientation to portrait-secondary orientation.

To unlock the screen orientation the end user is unrestricted to rotate the screen to any screen orientation that the system allows.

2.1 Screen orientation types

A screen can be in, or locked to, one of the following screen orientations:

Any
The screen can be rotated by the user to any orientation allowed by the device's operating system or by the end-user.
Default (unlocked)
The device's default behavior for when the screen is unlocked (i.e., the active orientation lock is null). This orientation is determined by the device's operating system, or the user agent, or controlled by the end-user, or possibly set by an installed web application. For example, when the screen orientation is unlocked and the user rotates the device, some devices will limit orientation changes to portrait-primary, landscape-primary, and landscape-secondary, but not to portrait-secondary.
Landscape
The screen's aspect ratio has a width greater than the height.
Natural
The most natural orientation for the device's display as determined by the user agent, the user, the operating system, or the screen itself. For example, a device viewed, or held upright in the user's hand, with the screen facing the user. A computer monitor are commonly naturally landscape-primary, while a mobile phones are commonly naturally portrait-primary.
Portrait
The screen's aspect ratio has a height greater than the width.
Primary
The device's screen natural orientation for either portrait or landscape.
Secondary
The opposite of the device's screen primary orientation for portrait or landscape.

2.2 The current screen orientation type and angle

The screen of the output device has the following associated concepts:

Active orientation lock
The screen orientation, represented as a OrientationLockType, to which the screen is locked, or null when unlocked.
Current orientation angle
The angle in degrees that the screen is rotated counter-clockwise from its natural orientation as derived by the screen orientation values list.
Current orientation type
The screen orientation of the screen, represented as a OrientationType.

The screen orientation values lists below standardize the angles associated with each screen orientation type for screens with different natural orientations:

For screens with a natural portrait orientation:
For screens with a natural landscape orientation:

3. Extensions to the Document interface

3.1 Internal Slots

The Document interface is extended with the following internal slots:

Internal Slot Description
[[orientationPendingPromise]] Either null or a Promise. When assigned a Promise, that promise represents a request to lock the screen orientation.

4. Extensions to the Screen interface

WebIDLpartial interface Screen {
  [SameObject] readonly attribute ScreenOrientation orientation;
};

The Window object has an associated ScreenOrientation, which is a Screen's orientation object (i.e., the ScreenOrientation instance at window.screen.orientation).

5. ScreenOrientation interface

WebIDL[Exposed=Window]
interface ScreenOrientation : EventTarget {
  Promise<undefined> lock(OrientationLockType orientation);
  undefined unlock();
  readonly attribute OrientationType type;
  readonly attribute unsigned short angle;
  attribute EventHandler onchange;
};

5.1 Internal Slots

Internal Slot Description
[[angle]] Represents the screen's last known current orientation angle in degrees as an unsigned short as derived from the screen orientation values lists.
[[initialType]] Represents the screen's current orientation type when the browsing context was created.
[[type]] Represents the screen's last known current orientation type as an OrientationType enum value.

5.2 lock() method

When the lock() method is invoked with OrientationLockType orientation, the user agent MUST run the following steps.

The user agent MAY require a document and its associated browsing context to meet one or more pre-lock conditions in order to lock the screen orientation. See 10. Interaction with Web Application Manifest and 9. Interaction with Fullscreen API.

  1. Let document be this's relevant global object's associated Document.
  2. Run the common safety checks with document. If an exception is thrown, return a promise rejected with that exception and abort these steps.
  3. If the user agent does not support locking the screen orientation to orientation, return a promise rejected with a "NotSupportedError" DOMException and abort these steps.
  4. If document's [[orientationPendingPromise]] is not null, reject and nullify the current lock promise of document with an "AbortError".
  5. Set document's [[orientationPendingPromise]] to a new promise.
  6. Apply orientation lock orientation to document.
  7. Return document's [[orientationPendingPromise]].

5.3 unlock() method

When the unlock() method is invoked, the user agent MUST run the following steps:

  1. Let document be this's relevant global object's associated Document.
  2. Run the common safety checks with document. If an exception is thrown, re-throw that exception and abort these steps.
  3. If screen's active orientation lock is null, return undefined.
  4. If document's [[orientationPendingPromise]] is not null, reject and nullify the current lock promise of document with an "AbortError".
  5. Apply orientation lock null to document.
Note: Why does unlock() not return a promise?

unlock() does not return a promise because it is equivalent to locking to the default screen orientation which might or might not be known by the user agent. Hence, the user agent can not predict what the new orientation is going to be and even if it is going to change at all.

5.4 Common Safety Checks

The common safety checks for a Document document are the following steps:

  1. If document is not fully active, throw an "InvalidStateError" DOMException.
  2. If document has the sandboxed orientation lock browsing context flag set, throw "SecurityError" DOMException.
  3. If document's visibility state is "hidden", throw "SecurityError" DOMException.

5.5 type attribute

When getting, the type attribute returns this's [[type]].

5.6 angle attribute

When getting, the angle attribute returns this's [[angle]].

Note: What does the value given for angle represent?

5.7 onchange event handler attribute

The onchange attribute is an event handler IDL attribute for the onchange event handler, whose event handler event type is change.

6. OrientationLockType enum

WebIDLenum OrientationLockType {
  "any",
  "natural",
  "landscape",
  "portrait",
  "portrait-primary",
  "portrait-secondary",
  "landscape-primary",
  "landscape-secondary"
};

The OrientationLockType enum represents the screen orientations to which a screen can be potentially locked.

Note: Orientation support

7. OrientationType enum

WebIDLenum OrientationType {
  "portrait-primary",
  "portrait-secondary",
  "landscape-primary",
  "landscape-secondary"
};

The OrientationType enum values are used to represent the screen's current orientation type.

8. Algorithms

8.1 Initializing the ScreenOrientation object

When a browsing context context is created, the user agent MUST:

  1. Let screenOrientation be context's associated ScreenOrientation.
  2. Initialize screenOrientation's [[initialType]] internal slot to the screen's current orientation type.
  3. Initialize screenOrientation's [[type]] internal slot to the screen's current orientation type.
  4. Initialize screenOrientation's [[angle]] internal slot to the screen's current orientation angle.

8.2 Rejecting a document's current lock promise

When steps require to reject and nullify the current lock promise of Document document with a DOMString exceptionName, the user agent MUST:

  1. Assert: [[orientationPendingPromise]] is not null.
  2. Let promise be document's [[orientationPendingPromise]].
  3. Queue a global task on the DOM manipulation task source with document's relevant global object to reject promise with a new exceptionName DOMException.
  4. Set document's [[orientationPendingPromise]] to null.

8.3 Applying an orientation lock

When steps require to apply orientation lock of OrientationLockType? orientation to Document document, the user agent MUST perform do the following steps:

  1. If document stops being fully active while in parallel, and [[orientationPendingPromise]] is not null, reject and nullify the current lock promise of document with an "AbortError".
  2. Let topDocument be document's top-level browsing context's active document.
  3. Let descendantDocs be an ordered set consisting of topDocument's descendant navigables's active documents, if any, in tree order.
  4. For each doc in descendantDocs:
    1. If doc is document, continue.
    2. If doc [[orientationPendingPromise]] is null, continue.
    3. Reject and nullify the current lock promise of doc with an "AbortError".
  5. Run the following sub-steps in parallel:
    1. If document has stopped being fully active, and if the document's [[orientationPendingPromise]] is not null, reject and nullify the current lock promise of document with an "AbortError" and abort these steps.
    2. If orientation is null, unlock the screen orientation.
    3. Otherwise, attempt to lock the screen orientation to orientation. Depending on platform conventions, change how the viewport is drawn to match orientation.
    4. If the attempt fails due to previously-established user preference, or platform limitation, or any other reason:
      1. Set the screen's active orientation lock to null.
      2. Queue a task on the DOM manipulation task source with document's relevant global object to:
        1. If the document's [[orientationPendingPromise]] is not null, reject and nullify the current lock promise of document with a "NotSupportedError".
        2. Abort these steps.
      Note

      This can happen if the user has set a preference that prevents web applications from changing the screen orientation, or if the underlying platform, rather than the user agent, does not allow locking the screen orientation to the given orientation.

    5. Set the screen's active orientation lock to orientation and update the current orientation type and current orientation angle to reflect any changes to the screen orientation.
  6. Queue a global task on the DOM manipulation task source with document's relevant global object to:
    1. Let promise be document's [[orientationPendingPromise]].
      Note
    2. Set document's [[orientationPendingPromise]] to null.
    3. Run the screen orientation change steps with topDocument.
    4. If promise is not null, resolve promise with undefined.

8.4 Screen orientation change

When a user-agent determines that the screen's orientation has changed for a top-level browsing context, or the user moves the top-level browsing context to a different screen, then run the screen orientation change steps with the top-level browsing context's active document.

The screen orientation change steps for Document document are as follows:

  1. If document's visibility state is "hidden", abort these steps.
  2. Let type and angle be the screen's current orientation type and current orientation angle.
  3. Let screenOrientation be document's relevant global object's associated ScreenOrientation.
  4. If type is equal to screenOrientation's [[type]] and angle is equal to screenOrientation's [[angle]], abort these steps.
  5. Queue a global task on the user interaction task source with document's relevant global object to perform the following steps:
    1. Set screenOrientation's [[angle]] to angle.
    2. Set screenOrientation's [[type]] to type.
    3. Fire an event named "change" at screenOrientation.
  6. Let descendantDocs be an ordered set consisting of document's descendant navigables's active documents, if any, in tree order.
  7. For each doc in descendantDocs, run the screen orientation change steps with doc.

8.5 Handling page visibility changes

[HTML]'s update the visibility state runs the screen orientation change steps.

Note

8.6 Handling unloading documents

Whenever the unloading document cleanup steps run with a document, the user agent MUST run the following steps:

  1. If document is not a top-level browsing context's active document, abort these steps.
  2. Run the fully unlock the screen orientation steps with document.

8.7 Fully unlocking the orientation

The fully unlock the screen orientation steps for Document document are as follows:

  1. If document's [[orientationPendingPromise]] is not null, reject and nullify the current lock promise of document with an "AbortError".
  2. Let topDocument be document's top-level browsing context's active document.
  3. Apply orientation lock null to topDocument.

9. Interaction with Fullscreen API

A user agent SHOULD restrict the use of lock() to simple fullscreen documents as a pre-lock condition. [fullscreen]

When a document exits fullscreen, it also runs the fully unlock the screen orientation steps. [fullscreen]

10. Interaction with Web Application Manifest

The Web Application Manifest specification allows web applications to set the default screen orientation via the the orientation member.

A user agent SHOULD require installed web applications to be presented in the "fullscreen" display mode as a pre-lock condition.

11. Accessibility considerations

As users can have their devices mounted in a fixed orientation (e.g. on the arm of a wheelchair), developers that expect users to rotate their device when locking the screen orientation need to be aware of the Web Content Accessibility Guidelines (WCAG) 2.1's Orientation Success Criterion. The criterion makes it essential that content and functionality is available regardless of the screen orientation. When a particular orientation is essential, web applications must advise the user of the orientation requirements.

12. Privacy and Security Considerations

A screen's type and angle are a potential fingerprinting vector. The following mitigation help protect a user's privacy by not revealing how a device is being held, and also prevents the secondary orientation type and associated angles from being user for fingerprinting purposes.

To resist fingerprinting (e.g., in private browsing), user agents MAY:

  1. For the life of a top-level browsing context, behave as as if screen's natural orientation is [[initialType]].
  2. Restrict the possible return values of the type getter to "portrait-primary" or "landscape-primary". The screen aspect ratio determines which is returned.
  3. If the current orientation type matches [[initialType]], return 0 for the angle getter. Otherwise, return 90.
  4. If the screen orientation changes, only fire the change event when the current orientation type changes from portrait to landscape, or vice versa.

13. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MAY, MUST, and SHOULD in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

A. IDL Index

WebIDLpartial interface Screen {
  [SameObject] readonly attribute ScreenOrientation orientation;
};

[Exposed=Window]
interface ScreenOrientation : EventTarget {
  Promise<undefined> lock(OrientationLockType orientation);
  undefined unlock();
  readonly attribute OrientationType type;
  readonly attribute unsigned short angle;
  attribute EventHandler onchange;
};

enum OrientationLockType {
  "any",
  "natural",
  "landscape",
  "portrait",
  "portrait-primary",
  "portrait-secondary",
  "landscape-primary",
  "landscape-secondary"
};

enum OrientationType {
  "portrait-primary",
  "portrait-secondary",
  "landscape-primary",
  "landscape-secondary"
};

B. Index

B.1 Terms defined by this specification

B.2 Terms defined by reference

C. Acknowledgments

Thanks Christophe Dumez, Anne van Kesteren, Chundong Wang, Fuqiao Xue, and Chaals McCathie Nevile for their useful comments.

Special thanks to Chris Jones and Jonas Sicking for their contributions to the initial design of this API.

D. References

D.1 Normative references

[appmanifest]
Web Application Manifest. Marcos Caceres; Kenneth Christiansen; Matt Giuca; Aaron Gustafson; Daniel Murphy; Anssi Kostiainen. W3C. 2 May 2023. W3C Working Draft. URL: https://www.w3.org/TR/appmanifest/
[cssom-view]
CSSOM View Module. Simon Pieters. W3C. 17 March 2016. W3C Working Draft. URL: https://www.w3.org/TR/cssom-view-1/
[dom]
DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[fullscreen]
Fullscreen API Standard. Philip Jägenstedt. WHATWG. Living Standard. URL: https://fullscreen.spec.whatwg.org/
[HTML]
HTML Standard. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[mediaqueries-5]
Media Queries Level 5. Dean Jackson; Florian Rivoal; Tab Atkins Jr.; Daniel Libby. W3C. 18 December 2021. W3C Working Draft. URL: https://www.w3.org/TR/mediaqueries-5/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[WCAG21]
Web Content Accessibility Guidelines (WCAG) 2.1. Andrew Kirkpatrick; Joshue O'Connor; Alastair Campbell; Michael Cooper. W3C. 5 June 2018. W3C Recommendation. URL: https://www.w3.org/TR/WCAG21/
[WEBIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/