The Screen Orientation API

W3C Working Draft

More details about this document
This version:
https://www.w3.org/TR/2022/WD-screen-orientation-20221012/
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://w3c-test.org/screen-orientation/
Editor:
Marcos Cáceres (Apple Inc.)
Feedback:
GitHub w3c/screen-orientation (pull requests, new issue, open issues)
Browser support:
caniuse.com

Abstract

For web applications, the Screen Orientation API exposes the type and angle of a device's current screen orientation, and dispatches events if the device's screen orientation changes. This allows web applications to programmatically adapt the user experience for many possible screen orientations in concert with CSS. If supported and if certain preconditions are met, the API also provides the ability to lock the screen orientation. This is useful in applications such as computer games where users physically rotate the device but the screen orientation itself mustn't 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 2 November 2021 W3C Process Document.

1. Examples

This section is non-normative.

1.1 Locking to a specific orientation and unlocking

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.

<script>
function updateLockButton() {
  const lockButton = document.getElementById("button");
  const buttonOrientation = getOppositeOrientation();
  lockButton.textContent = `Lock to ${buttonOrientation}`;
}

function getOppositeOrientation() {
  const { type } = screen.orientation;
  return 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

The Window object has an associated Screen, which is a Screen object.

A browsing context A is called a descendant browsing context of a browsing context B if and only if B is an ancestor browsing context of A.

2.1 Screen orientation types and locks

To lock the screen orientation to an orientation means that the screen can only be rotated by the user to specific orientations (possibly at the exclusion of other orientations). For example, locking the orientation to landscape means that the screen can be rotated by the user to landscape-primary and landscape-secondary, and not to any portrait orientation.

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

Natural:
The 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, while a mobile phones are commonly naturally portrait.
Landscape:
The screen's aspect ratio has a width greater than the height.
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.
Any:
The screen can be rotated by the user to any orientation allowed by the device's operating system or by the end-user.
The default screen orientation:
The orientation to which the screen is locked when there is no active orientation lock (i.e., the orientation is "unlocked"). This orientation is determined by the device's operating system, or the user agent (e.g., 9.2 Interaction with Web Application Manifest), or controlled by the end-user.

2.2 The current screen orientation type and angle

The screen of the output device has a current orientation type and a current orientation angle. To derive these values, the user agent MUST update the orientation information when a browsing context is created. The relationship between the current orientation type and the current orientation angle MUST be kept consistent.

The screen orientation values table presents the possible value for the current orientation type and current orientation angle. The table specifies the primary and secondary values that are determined by the device's natural orientation and the possibilities available to the user agent for setting the other primary and secondary orientation values.

The screen orientation values table
In the natural orientation is... Primary Orientation 1 Secondary Orientation 1 Primary Orientation 2 Secondary Orientation 2
Portrait portrait-primary
angle 0
portrait-secondary
angle 180
landscape-primary
angle 90 or angle 270
landscape-secondary
Set at the angle not used for landscape-primary
Landscape landscape-primary
angle 0
landscape-secondary
angle 180
portrait-primary
angle 90 or angle 270
portrait-secondary
The angle not used for portrait-primary.
Best Practice 1: angle and type relationship

Never assume any cross-devices relationship between the screen orientation type and the screen orientation angle. Any assumption would be wrong given that a device might have 90 and 270 as the angles for landscape types but another device will have 0 and 180, depending on its natural orientation. Instead, it is recommended to check during runtime the relationship between angle and type.

2.3 Locking the screen orientation

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 in order to allow an orientation lock. See, for example, 9.1 Interaction with Fullscreen API).

The user agent MAY reject all attempts to lock the screen orientation if the platform conventions do not expect web applications to change the screen orientation. For example, on most desktop platforms, web applications can not change the screen orientation.

3. Extensions to the Screen interface

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

4. 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;
};

4.1 Internal Slots

Internal Slot Description
[[angle]] The current orientation angle in degrees as an unsigned short.
[[type]] The current orientation type of the screen, represented as an OrientationType enum value.

4.2 lock() method

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

  1. Let document be this's relevant global object's associated Document.
  2. If document is not fully active, return a promise rejected with an "InvalidStateError" DOMException.
  3. If the user agent does not support locking the screen orientation due to previously-established user preference, security risk, or platform limitation, return a promise rejected with a "NotSupportedError" DOMException and abort these steps.
  4. If document has the sandboxed orientation lock browsing context flag set, or doesn't meet the pre-lock conditions, return a promise rejected with a "SecurityError" DOMException and abort these steps.
  5. If document's [[orientationPendingPromise]] is not null:
    1. Let currentLockPromise be document's [[orientationPendingPromise]].
    2. Queue a global task on the DOM manipulation task source with this's relevant global object to reject currentLockPromise with an "AbortError" DOMException.
  6. Set document's [[orientationPendingPromise]] to a new promise.
  7. Return document's [[orientationPendingPromise]] and in parallel:
    1. Let descendantDocs be an ordered set consisting of documents's descendant browsing contexts' active documents, if any, in tree order.
    2. For each doc in descendantDocs:
      1. If doc [[orientationPendingPromise]] is null, continue.
      2. Queue a global task on the DOM manipulation task source with doc's relevant global object to:
        1. Reject doc's [[orientationPendingPromise]] with "AbortError" DOMException.
        2. Set doc's [[orientationPendingPromise]] to null.
    3. Lock the orientation of document to orientation.
  8. If document stops being fully active, queue a global task on the DOM manipulation task source with this's relevant global object to reject [[orientationPendingPromise]] with an "AbortError" DOMException.
Note
If locking the orientation results in an orientation change, the promise will be resolved when the orientation changes.

4.3 unlock() method

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

  1. If document is not fully active, throw an "InvalidStateError" DOMException.
  2. Lock the screen orientation of this's relevant global object's associated Document to the default screen orientation.
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.

4.4 type attribute

When getting, return this's [[type]].

4.5 angle attribute

When getting, return this's [[angle]].

Note: What does the value given for angle represent?

angle represents how far the user has turned the device counterclockwise from the natural orientation. When the device is rotated 90° counterclockwise, the screen compensates by rotating 90° clockwise, so angle returns 90.

The screen orientation values table shows how the angle changes depending on the how the device is rotated.

4.6 onchange attribute

The onchange attribute is an event handler whose corresponding event handler event type is change.

5. 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 rotated.

6. OrientationType enum

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

The OrientationType enum represents the actual current screen orientation that the screen is in irrespective of which lock is applied.

7. Extensions to the Document interface

7.1 Internal Slots

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

8. Algorithms

8.1 Updating the orientation information

The steps to update the orientation information of a browsing context context:

  1. Let orientation be the OrientationType enum that matches the screen orientation of context.
  2. Let angle be the angle that matches the orientation from the screen orientation values table.
  3. Set associated Screen's ScreenOrientation's' [[type]] internal slot to orientation.
  4. Set associated Screen's ScreenOrientation's' [[angle]] internal slot to angle.

8.2 Locking the orientation

The steps to lock the orientation of document to orientation are as follows.

  1. Set the Document's [[orientationLock]] to orientation.
  2. If the active orientation lock is not the document's [[orientationLock]], abort these steps.
  3. If the active orientation lock value is equal to orientation value, abort these steps.
  4. If orientations contains only one value, run the following sub-steps:
    1. Let orientation be the value contained in orientations.
    2. Change how the viewport is drawn so that the Document's current orientation type will be equal to orientation.
    3. After the change has happened, prevent the Document's top-level browsing context's screen orientation from changing until those steps are run again.
    4. Abort these steps.
  5. If the Document's current orientation type is not part of orientations, change how the viewport is drawn such as the Document's current orientation type will be equal to one of orientations' values.
  6. Otherwise, depending on platform conventions, change how the viewport is drawn in order to make it match another screen orientation type.
  7. Allow the user to change the screen orientation to any value part of orientations and only those values until those steps are run again. The method to define the current screen orientation has to match the platform conventions.

8.3 Determining the active orientation lock

An orientation lock is in place when a document has an active orientation lock.

The steps to determine the active orientation lock are as follows:

  1. If there is only one top-level browsing context with a document whose visibility state is "visible", the active orientation lock is the document's [[orientationLock]].
  2. Otherwise, if there are more than one top-level browsing context with a document that has a visibility state is "visible" but only one of those documents is focused, the [=Document/active orientation lock is the focused document's [[orientationLock]].
  3. Otherwise, the active orientation lock SHOULD be the latest focused document's [[orientationLock]], unless stated otherwise by the active platform conventions.

Whenever the active orientation lock changes, the user agent MUST run the steps to lock the orientation of the Document to the Document's [[orientationLock]].

Whenever a top-level browsing context is navigated, the user agent MUST return the screen to the default screen orientation.

8.3.1 Screen orientation change

Whenever the viewport's angle changes, the user agent MUST run the following steps as part of the next animation frame:

  1. Let descendantDocs be an ordered set consisting of documents's descendant browsing contexts' active documents, if any, in tree order.
  2. For each doc in descendantDocs:
    1. If doc's visibility state is "hidden", abort these steps.
    2. Update the orientation information of doc's browsing context.
    3. If the orientation change was triggered by a user gesture such as the user turning the device, as opposed to a call to lock(), the task MUST be annotated with process user orientation change when running the next step.
    4. Queue a task to on the DOM manipulation task source to:
      1. Fire an event named "change" at doc's relevant global object's associated Screen's orientation attribute.
      2. If doc's [[orientationPendingPromise]] is not null:
        1. Resolve doc's [[orientationPendingPromise]] with undefined.
        2. Set doc's [[orientationPendingPromise]] to null.

An algorithm is triggered by a user generated orientation change if the task in which the algorithm is running is annotated with process user orientation change.

Whenever a Document's visibility state becomes "visible", the user agent MUST run the following sub-steps as part of the next animation frame:

  1. Let type and angle be the current orientation type and current orientation angle, respectively.
  2. Update the orientation information of the document's browsing context.
  3. If type is different from the current orientation type or angle from the current orientation angle, run the following sub-steps:
    1. If the orientation change was triggered by a user gesture such as the user turning the device, as opposed to a call to lock(), the task MUST be annotated with process user orientation change when running the next step.
    2. Fire an event named "change" at doc's relevant global object's associated Screen's orientation attribute.
    3. If the Document's [[orientationPendingPromise]] is not null:
      1. Resolve the Document's [[orientationPendingPromise]] with undefined.
      2. Set the Document's [[orientationPendingPromise]] to null.
Note

Developers need to be aware that a orientation object from a Document with a "hidden" visibility state will not receive an orientation change event. This is to prevent unnecessary changes to layout, etc. in the non-visible web application.

9. Interactions with other specifications

This section explains how this specification interacts with other related specifications of the platform.

9.1 Interaction with Fullscreen API

As a pre-lock condition, a user agent SHOULD restrict locking the screen orientation to simple fullscreen documents.

9.2 Interaction with Web Application Manifest

This section is non-normative.

The Web Application Manifest allows web applications to set the Document's default screen orientation.

9.3 Interaction with Web Content Accessibility Guidelines

This section is non-normative.

The Web Content Accessibility Guidelines (WCAG) 2.1 includes a Success Criterion related to screen orientation.

​The intent of this Success Criterion is to ensure that all essential content and functionality is available regardless of the display orientation (portrait or landscape). Some websites and applications automatically set the screen to a particular display orientation and expect that users will respond by rotating their device to match.

However, some users may have their devices mounted in a fixed orientation (e.g. on the arm of a wheelchair). Therefore, websites and applications need to support both orientations by making sure essential content and functionality is available in each orientation. While the order of content and method of functionality may have differences the content and functionality must always be available. When a particular orientation is essential, the user needs to be advised of the orientation requirements.

10. Privacy and Security Considerations

This section is non-normative.

10.1 Access to aspects of a user's local computing environment

The screen orientation type and angle of the device can be accessed with the API specified in this document, and can be a potential fingerprinting vector.

11. 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

[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/
[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/
[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
[web-animations]
Web Animations. Brian Birtles; Robert Flack; Stephen McGruer; Antoine Quint. W3C. 8 September 2022. W3C Working Draft. URL: https://www.w3.org/TR/web-animations-1/
[WEBIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

D.2 Informative references

[appmanifest]
Web Application Manifest. Marcos Caceres; Kenneth Christiansen; Matt Giuca; Aaron Gustafson; Daniel Murphy; Anssi Kostiainen. W3C. 17 February 2022. W3C Working Draft. URL: https://www.w3.org/TR/appmanifest/
[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/