TheScreen 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. This API is particularly useful for applications such as computer games, where users physically rotate the device, but the screen orientation itself should not change. The API restricts locking the screen orientation only if certain [=pre-lock conditions=] are met.
This document is a work in progress.
In this example, selecting the "Lock" button requests to go into fullscreen and then locks the screen to the opposite orientation. Selecting the "Unlock" button unlocks the screen.
<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> Lock to... </button> <button> Unlock </button>Tolock 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.
Tounlock the screen orientation the end user is unrestricted to rotate the screen to any [=screen orientation=] that the system allows.
A screen can be in, or [=locked=] to, one of the followingscreen orientations:
The screen of the output device has the following associated concepts:
Thescreen orientation values lists below standardize the angles associated with each screen orientation type for screens with different [=natural=] orientations:
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. |
partial interface Screen { [SameObject] readonly attribute ScreenOrientation orientation; };The {{Window}} object has anassociated `ScreenOrientation`, which is a {{Screen}}'s {{Screen/orientation}} object (i.e., the {{ScreenOrientation}} instance at `window.screen.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; };| Internal Slot | Description |
|---|---|
| [[\angle]] | Represents the screen's last known [=Screen/current orientation angle=] in degrees as an {{unsigned short}} as derived from the [=screen orientation values lists=]. |
| [[\initialType]] | Represents the screen's [=Screen/current orientation type=] when the [=browsing context=] was created. |
| [[\type]] | Represents the screen's last known [=Screen/current orientation type=] as an {{OrientationType}} enum value. |
pre-lock conditions are optional requirements that a [=user agent=] MAY impose before allowing screen orientation locking. Common pre-lock conditions include requiring the document to be in fullscreen mode or being part of an installed web application. See [[[#appmanifest-interaction]]] and [[[#fullscreen-interaction]]] for specific examples.
When the {{lock()}} method is invoked with {{OrientationLockType}} |orientation:OrientationLockType|, the [=user agent=] MUST run the following steps.
When the {{unlock()}} method is invoked, the [=user agent=] MUST run the following steps:
{{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.
Thecommon safety checks for a {{Document}} |document:Document| are the following steps:
When getting, the {{type}} attribute returns [=this=]'s {{ScreenOrientation/[[type]]}}.
When getting, the {{angle}} attribute returns [=this=]'s {{ScreenOrientation/[[angle]]}}.
The {{ScreenOrientation/angle}} attribute represents how far the screen has rotated from its [=natural=] orientation. Thescreen orientation values lists specify how the angle changes depending on how the screen is rotated.
The {{onchange}} attribute is an [=event handler IDL attribute=] for the {{onchange}} [=event handler=], whose [=event handler event type=] ischange.
enum 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=].
User agents might only support a subset of the possible {{OrientationLockType}} values. For example, a user agent might not support locking to the `"portrait-secondary"` or `"landscape-secondary"` orientations.
enum OrientationType { "portrait-primary", "portrait-secondary", "landscape-primary", "landscape-secondary" };The {{OrientationType}} enum values are used to represent the screen's [=Screen/current orientation type=].
When a [=browsing context=] |context| is created, the [=user agent=] MUST:
When steps require toreject and nullify the current lock promise of {{Document}} |document| with a {{DOMString}} |exceptionName|, the [=user agent=] MUST:
When steps require toapply orientation lock of {{OrientationLockType?}} |orientation| to {{Document}} |document|, the [=user agent=] MUST perform the following steps:
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|. Note that differences in user preferences or platform capabilities could potentially be used for fingerprinting, as they may create detectable patterns in lock failure behavior.
As the promise needs to resolve after a "change" event is fired, we keep a reference to prevent it from being aborted by an event's handler function calling {{ScreenOrientation/lock()}}.
When a user-agent determines that the screen's orientation has changed for a [=top-level traversable=], or the user moves the [=top-level browsing context=] to a different screen, then run the [=screen orientation change steps=] with the [=top-level traversable=]'s [=navigable/active document=].
Thescreen orientation change steps for {{Document}} |document:Document| are as follows:
[[HTML]]'s "update the visibility state" algorithm runs the [=screen orientation change steps=].
Developers need to be aware that [=documents=] that are not [=Document/fully active descendant of a top-level traversable with user attention=] will not receive orientation change events. However, once a [=document=] meets these requirements again, it will receive change events reflecting the current orientation.
Whenever the [=unloading document cleanup steps=] run with a |document|, the user agent MUST run the following steps:
Thefully unlock the screen orientation steps for {{Document}} |document:Document| are as follows:
A user agent MUST restrict the use of {{ScreenOrientation/lock()}} to simple fullscreen documents as a [=pre-lock condition=]. This requirement prevents fingerprinting through differences in user agent behavior regarding orientation locking permissions. [[fullscreen]]
When a [=document=] exits fullscreen, it also runs the [=fully unlock the screen orientation steps=]. [[fullscreen]]
The [[[appmanifest]]] specification allows web applications to set the [=default screen orientation=] via the the [=manifest/orientation=] member.
A user agent SHOULD require [=installed web applications=] to be presented in the "fullscreen" [=display mode=] as a [=pre-lock condition=].
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 [[[WCAG21]]]'sOrientation Success Criterion. The criterion makes itessential that content and functionality is available regardless of the [=screen orientation=]. When a particular orientation isessential, web applications must advise the user of the orientation requirements.
A screen's [=Screen/current orientation type|type=] and [=Screen/current orientation angle|angle=] are a potential fingerprinting vectors. The following mitigations help protect a user's privacy by not revealing how a device is being held, and also prevent the [=secondary=] orientation type and associated angles from being used for fingerprinting purposes.
To protect user privacy, orientation change events are subject to several delivery restrictions:
The requirement for [=documents=] to be [=Document/fully active descendant of a top-level traversable with user attention=] ensures that orientation events are only delivered to documents in windows that are both visible at the system level and have the user's attention (either through focus or the ability to receive keyboard input). The additional visibility state check provides defense in depth. These restrictions prevent background tabs, hidden windows, and minimized applications from collecting orientation data for fingerprinting purposes.
To resist fingerprinting, user agents SHOULD implement the following protections, particularly in privacy-conscious contexts such as private browsing modes:
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.