Copyright © 2022 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
The Screen Orientation API provides the ability to read the screen orientation type and angle, to be informed when the screen orientation changes, and, if certain pre-conditions are met, to lock the screen to a given orientation.
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.
This section is non-normative.
For web applications, the Screen Orientation API exposes the type and angle of a device's current screen orientation, and can provide notification if the device's orientation changes. This allows web applications to programmatically adapt the user experience for many possible screen orientations (in concert with CSS). The API also allows locking the screen to a particular orientation. This is useful in applications such as computer games where users physically rotate the device but the screen orientation itself mustn't change.
This section is non-normative.
In this example, clicking the "Lock" button makes a request to go into fullscreen and then lock the screen to the opposite orientation. Pressing the "Unlock" button unlocks the screen so it rotates if the user turns the device.
The developer console logs the change in orientation type and angle.
<script>
function fullScreenCheck() {
if (document.fullscreenElement) return;
return document.documentElement.requestFullscreen();
}
function updateDetails(lockButton) {
const buttonOrientation = getOppositeOrientation();
lockButton.textContent = `Lock to ${buttonOrientation}`;
}
function getOppositeOrientation() {
const { type } = screen.orientation;
return type.startsWith("portrait") ? "landscape" : "portrait";
}
async function rotate(lockButton) {
try {
await fullScreenCheck();
} catch (err) {
console.error(err);
}
const newOrientation = getOppositeOrientation();
await screen.orientation.lock(newOrientation);
updateDetails(lockButton);
}
function show() {
const { type, angle } = screen.orientation;
console.log(`Orientation type is ${type} & angle is ${angle}.`);
}
screen.orientation.addEventListener("change", () => {
show();
updateDetails(document.getElementById("button"));
});
window.addEventListener("load", () => {
show();
updateDetails(document.getElementById("button"));
});
</script>
<button onclick="rotate(this)" id="button">
Lock
</button>
<button onclick="screen.orientation.unlock()">
Unlock
</button>
This example waits to go into fullscreen, then locks to landscape
before calling ready()
.
<script>
function ready() {
const { type } = screen.orientation;
console.log(`Fullscreen and locked to ${type}. Ready!`);
}
async function start() {
await document.body.requestFullscreen();
await screen.orientation.lock("landscape");
ready();
}
</script>
<button onclick="start()">
Start
</button>
In this example, if the Screen Orientation API is not
supported, or the screen orientation lock
()
rejects, the user is
alerted to rotate their screen manually to landscape.
<script>
function start() {
/* Start application when in correct orientation */
}
async function rotate() {
try {
await screen.orientation.lock("landscape");
} catch (err) {
console.error(err);
}
const matchLandscape = matchMedia("(orientation: landscape)");
if (matchLandscape.matches) return start();
addEventListener("orientationchange", function listener() {
matchLandscape.addListener(function mediaChange(e) {
if (!e.matches) return;
removeEventListener("orientationchange", listener);
matchLandscape.removeListener(mediaChange);
start();
});
});
alert("To start, please rotate your screen to landscape.");
}
</script>
<button onclick="start()">
Start
</button>
Landscape-primary is an orientation where the screen width is greater than the screen height. If the device's natural orientation is landscape, then it is in landscape-primary when held in that position. If the device's natural orientation is portrait, the user agent sets landscape-primary from the two options as shown in the screen orientation values table.
Landscape-secondary is an orientation where the screen width is greater than the screen height. If the device's natural orientation is landscape, it is in landscape-secondary when rotated 180º from its natural orientation. If the device's natural orientation is portrait, the user agent sets landscape-secondary from the two options as shown in the screen orientation values table.
Portrait-primary is an orientation where the screen width is less than or equal to the screen height. If the device's natural orientation is portrait, then it is in portrait-primary when held in that position. If the device's natural orientation is landscape, the user agent sets portrait-primary from the two options as shown in the screen orientation values table.
Portrait-secondary is an orientation where the screen width is less than or equal to the screen height. If the device's natural orientation is portrait, then it is in portrait-secondary when rotated 180º from its natural position. If the device's natural orientation is landscape, the user agent sets portrait-secondary from the two options as shown in the screen orientation values table.
Portrait is an orientation where the screen width is less than or equal to the screen height and depending on platform convention locking the screen to portrait can represent portrait-primary, portrait-secondary or both.
Landscape is an orientation where the screen width is greater than the screen height and depending on platform convention locking the screen to landscape can represent landscape-primary, landscape-secondary or both.
Natural is an orientation that refers to either portrait-primary or landscape-primary depending on the device's usual orientation. This orientation is usually provided by the underlying operating system.
Any is an orientation that means the screen can be locked to any one of portrait-primary, portrait-secondary, landscape-primary and landscape-secondary.
The default screen orientation is the orientation to which the screen is locked when there is no current orientation lock. This orientation is determined by the device's operating system, or the user agent (e.g., 10.2 Interaction with Web Application Manifest), or controlled by the end-user.
Currently default orientation is defined with the following:
A <a>document</a>'s <dfn>default orientation</dfn> is the set of
orientations to which the screen orientation is locked when it is not
explicitly locked by this API or any other means.
It would be great to get some clarification on why default orientation is a set? From looking at the android docs it looks like the system decides on one orientation if none is specified.
@mounirlamouri Could you please explain this further?
Relates to #104
All Document
objects have a current orientation type
and a current orientation angle.
When the Document
is created, the user agent MUST
update the orientation information of the Document
. Doing
so initializes the current orientation type and the current
orientation angle.
For a given Document
, the current orientation type and the
current orientation angle are strongly linked in the sense
that for any given type, there will be a specific angle associated.
One primary orientation will always be determined by the natural orientation of the device and this will then determine the secondary value of its related orientation.
For example a device held in its natural portrait orientation
would have a current orientation of portrait-primary
and its
portrait-secondary
orientation would be its position when
rotated 180°.
The user agent can associate the other *-primary
and
*-secondary
values at will. For example, it can be based on the
device preferred angles, the user's preferred orientations or the
current orientation when the application starts.
The screen orientation values table presents the possible
orientation types: portrait-primary
,
portrait-secondary
, landscape-primary
and
landscape-secondary
. The table shows 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.
Natural Orientation | Primary Orientation 1 | Secondary Orientation 1 | Primary Orientation 2 | Secondary Orientation 2 |
---|---|---|---|---|
Portrait |
portrait-primaryangle 0
|
portrait-secondaryangle 180
|
landscape-primary User agent to set at either angle 90 or angle
270
|
landscape-secondary Set at the angle not used for landscape-primary |
Landscape |
landscape-primaryangle 0
|
landscape-secondaryangle 180
|
portrait-primary User agent to set at either angle 90 or angle
270
|
portrait-secondary Set at the angle not used for portrait-primary |
Once the user agent has set the primary and secondary values
from the options in the screen orientation values table, the
current orientation type and the current orientation
angle relation MUST be kept consistent for any given
Document
.
ScreenOrientation
.angle
and
ScreenOrientation
.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.
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. For
example, a user agent might require a Document
's
top-level browsing context to be fullscreen (see 10.1
Interaction with Fullscreen API) in order to allow an
orientation lock.
The user agent MAY reject all attempts to lock the screen orientation if the platform conventions do not expect applications to be able to change the screen orientation. For example, on most desktop platforms, applications can not change the screen orientation.
If the user agent supports locking the screen orientation, it
MUST allow the screen to be locked to all of the states of the
OrientationLockType
enum.
The [[orientationLock]]
internal slot represents the
Document
's orientation lock.
An orientation lock is in place when the screen has successfully been locked to a specific orientation.
From the perspective of a Document
, locking to the default
screen orientation is equivalent to unlocking because it means
that it no longer has a lock applied.
This does not mean that the [[defaultOrientation]]
will only contain the item any. The default screen
orientation is likely device-specific and
[[defaultOrientation]]
could for example contain
portrait-primary and/or landscape-primary.
Alternatively, the user could restrict the default orientation to a
specific orientation via some OS or browser level preference for
accessibility reasons. The user agent can also set the default
orientation e.g., 10.2
Interaction with Web Application Manifest.
WebIDLpartial interface Screen {
[SameObject] readonly attribute ScreenOrientation
orientation
;
};
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
;
};
When the lock
()
method is invoked, the user agent MUST run
the apply an orientation lock steps to this's relevant global object's associated Document
using
orientation.
When the unlock
()
method is invoked, the user agent MUST
run the steps to lock the orientation of this's relevant global object's associated Document
to its default screen
orientation.
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.
When getting the type
attribute, the user agent MUST
return this's relevant global object's associated Document
's current orientation type.
When getting the angle
attribute, the user agent MUST
return this's relevant global object's associated Document
's current orientation angle.
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.
The value returned by this property is always in the range 0-359. It never returns negative values.
The onchange
attribute is an event handler whose
corresponding event handler event type is "change"
.
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 locked.
any
" enum value represents the any orientation,
natural
" enum represents the natural
orientation,
landscape
" enum represents the landscape
orientation,
portrait
" enum represents the portrait
orientation,
portrait-primary
" enum represents the
portrait-primary orientation,
portrait-secondary
" enum represents the
portrait-secondary orientation,
landscape-primary
" enum represents the
landscape-primary orientation,
landscape-secondary
" enum represents the
landscape-secondary orientation.
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.
portrait-primary
" enum represents the
portrait-primary orientation,
portrait-secondary
" enum represents the
portrait-secondary orientation,
landscape-primary
" enum represents the
landscape-primary orientation,
landscape-secondary
" enum represents the
landscape-secondary orientation.
Internal Slot | Description |
---|---|
[[orientationLock]] |
The [[orientationLock]] represents a
Document 's orientation lock as an ordered set
of OrientationType .
|
[[defaultOrientation]] | An ordered set of orientations to which the screen orientation is locked when not explicitly locked by this API or any other means. |
[[orientationPendingPromise]] |
Either null or a Promise . When assigned a Promise ,
that promise represents a request to lock the screen to one of
the supported orientations. The promise resolves after locking
the orientation succeeds or rejects if locking fails.
|
The steps to update the orientation information of a
Document
are as follows:
Document
's current orientation type to
landscape-primary
or landscape-secondary
.
Document
's current orientation type
to portrait-primary
or portrait-secondary
.
Document
's
current orientation angle to the clockwise angle in degrees
between the orientation of the viewport as it is drawn and the
natural orientation of the device (i.e., the top of the
physical screen). This is the opposite of the physical rotation. In
other words, if a device is turned 90 degrees on the right, the
current orientation angle would be 270 degrees. The
screen orientation values table gives the options for each
orientation and possible associated angles.
The steps to apply an orientation lock to a Document
document using orientation are as
follows:
NotSupportedError
"
DOMException
and abort these steps.
"SecurityError"
DOMException
and abort these steps.
[[orientationPendingPromise]]
is not null
:
[[orientationPendingPromise]]
.
AbortError
"
DOMException
.
[[orientationPendingPromise]]
to a new promise.
[[orientationPendingPromise]]
and in parallel:
Document
.
Document
's
[[orientationPendingPromise]]
is not null
:
Document
whose
[[orientationPendingPromise]]
is not null
.
[[orientationPendingPromise]]
with
"AbortError"
DOMException
.
[[orientationPendingPromise]]
to null
.
portrait-primary
or portrait-secondary
or
landscape-primary
or landscape-secondary
landscape
landscape-primary
, or landscape-secondary
, or both to
orientations.
portrait
portrait-primary
, or portrait-secondary
, or both to
orientations.
natural
portrait-primary
or landscape-primary
to
orientations such as the associated current
orientation angle is 0.
any
portrait-primary
, portrait-secondary
,
landscape-primary
and landscape-secondary
to
orientations.
[[orientationPendingPromise]]
with
undefined
and set [[orientationPendingPromise]]
to
null
.
The steps to lock the orientation to orientations are as follows.
Document
's [[orientationLock]]
to orientations.
Document
's
[[orientationLock]]
, abort these steps.
Document
's
current orientation type will be equal to orientation.
Document
's
top-level browsing context's screen orientation from
changing until those steps are run again.
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.
The steps to determine the active orientation lock are as follows:
Document
's
[[orientationLock]]
.
Document
whose visibility state
is "visible" but only one of those Document
s is focused, the
active orientation lock is the focused Document
's
[[orientationLock]]
.
Document
's [[orientationLock]]
,
unless stated otherwise by the 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 lock the orientation of the
Document
to the Document
's
[[defaultOrientation]]
.
Whenever the viewport's angle changes, the user agent MUST run the following steps as part of the next animation frame:
Document
.
lock
()
, the task MUST be annotated with process user
orientation change
when running the next step.
change
at doc's
orientation
attribute.
[[orientationPendingPromise]]
is
not null
:
[[orientationPendingPromise]]
with
undefined
.
[[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:
Document
's
current orientation type and current orientation angle.
Document
.
Document
's current
orientation type or angle from the Document
's current
orientation angle, run the following sub-steps:
lock
()
, the task MUST be annotated
with process user orientation change
when running the next
step.
change
at the Document
's
orientation
object.
Document
's
[[orientationPendingPromise]]
is not null
:
Document
's
[[orientationPendingPromise]]
with undefined
.
Document
's
[[orientationPendingPromise]]
to null
.
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.
This section explains how this specification interacts with other related specifications of the platform.
As a pre-lock condition, a user agent MAY restrict locking the
screen orientation exclusively to when the top-level browsing
context's Document
's is full screen. When that pre-lock
condition applies, whenever the Document
's fullscreen
element is empty and a screen orientation lock is applied,
the user agent MUST lock the orientation of the
Document
to the Document
's default screen orientation.
This section is non-normative.
The Web Application Manifest allows web applications to set the
Document
's default screen orientation.
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 power 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.
This section is non-normative.
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.
The screen orientation type can already be known by using the screen width and height. In practice, the additional information provided with the API concerning the angle of the device and the primary or secondary screen orientation is unlikely to be used by any competent attack.
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.
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
"
};
angle
attribute for ScreenOrientation
§5.4"any"
enum value for OrientationLockType
§6.[[defaultOrientation]]
internal slot for Document
§8.1"landscape"
enum value for OrientationLockType
§6.lock()
method for ScreenOrientation
§5.1"natural"
enum value for OrientationLockType
§6.onchange
attribute for ScreenOrientation
§5.5orientation
attribute for Screen
§4.[[orientationLock]]
internal slot for Document
§8.1[[orientationPendingPromise]]
internal slot for Document
§8.1"portrait"
enum value for OrientationLockType
§6.ScreenOrientation
interface
§5.type
attribute for ScreenOrientation
§5.3unlock()
method for ScreenOrientation
§5.2Screen
interface
Document
interface
EventTarget
interface
Document
)
EventHandler
Document
)
AbortError
exception
DOMException
interface
[Exposed]
extended attribute
NotSupportedError
exception
Promise
interface
[SameObject]
extended attribute
undefined
type
unsigned short
type
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.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: