版权声明 © 2025 万维网联盟 (World Wide Web Consortium)。适用 W3C® 责任限制、商标及宽松文档许可规则。
Screen Orientation 规范统一了设备屏幕方向的类型和角度,并提供了锁定与解锁的手段。该规范定义的 API 暴露了设备屏幕方向的当前类型和角度,并在方向变化时分发事件。这使得 Web 应用能够以编程方式适配多种屏幕方向,并可配合 CSS 使用。该 API 对于如电脑游戏等场景尤为有用——用户会实际旋转设备,但屏幕方向本身不应随之改变。只有在满足特定的预锁定条件时,API 才会限制锁定屏幕方向。
本节描述了本文件发布时的状态。当前的 W3C 出版物列表和本技术报告的最新版本可以在 W3C 标准和草案索引中找到。
本文件仍在持续完善中。
本文档由 Web 应用程序工作组发布,作为一份使用推荐标准轨道的工作草案。
发布为工作草案并不意味着 W3C 及其成员的认可。
这是一份草案文件,可能随时被其他文件更新、替换或废弃。将其作为进展中的工作以外的引用是不恰当的。
本文档由在一个受 W3C 专利政策 约束下运营的组织所编写。W3C 维护了一份 与该工作组交付成果相关的专利披露公开列表;该页面还包含披露专利的说明。任何知晓其认为包含 必要权利要求 的专利的个人,必须按照 W3C 专利政策第 6 节 的规定披露相关信息。
本文件受 2025 年 8 月 18 日 W3C 流程文档约束。
本节是非规范性的。
在本示例中,点击 “Lock” 按钮会请求进入全屏并将屏幕锁定到相反的方向。点击 “Unlock” 按钮则解锁屏幕。
<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>
要锁定屏幕方向为OrientationLockType orientation,意味着用户只能将屏幕旋转到特定的屏幕方向——可能会排除其他方向。可以旋转到的方向由用户代理、用户偏好、操作系统约定或屏幕本身决定。例如,将方向锁定为横向,则用户可以将屏幕旋转到横向主方向,并在系统允许的情况下可能兼容横向次方向,但不会切换到纵向次方向。
要解锁屏幕方向,最终用户可以自由将屏幕旋转到系统允许的任何屏幕方向。
null),设备的默认行为。此方向由操作系统、用户代理、最终用户或可能由已安装的 Web 应用设定。例如,当屏幕未锁定且用户旋转设备时,有些设备仅会在纵向主方向、横向主方向和横向次方向之间切换,而不会切换到纵向次方向。输出设备的屏幕具有以下关联概念
OrientationLockType 表示;在锁定时有值,否则为 null(未锁定)。OrientationType 枚举值表示。下面的屏幕方向值列表标准化了不同自然方向的屏幕上,各方向类型对应的角度。
Document 接口被扩展了以下内部槽位
| 内部槽 | 描述 |
|---|---|
| [[orientationPendingPromise]] | 要么为 null,要么为Promise。当被赋值为Promise时,该 Promise 代表对锁定屏幕方向的请求。 |
WebIDLpartial interface Screen {
[SameObject] readonly attribute ScreenOrientation orientation;
};
Window 对象拥有一个关联的 ScreenOrientation,即Screen 的orientation 对象(即 window.screen.orientation 处的ScreenOrientation 实例)。
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;
};
| 内部槽 | 描述 |
|---|---|
| [[angle]] | 表示屏幕最近一次记录的当前方向角度(单位:度),以unsigned short 表示,取自屏幕方向值列表。 |
| [[initialType]] | 表示在创建浏览上下文时,屏幕的当前方向类型。 |
| [[type]] | 表示屏幕最近一次记录的当前方向类型,以OrientationType 枚举值表示。 |
预锁定条件是用户代理在允许屏幕方向锁定前可能施加的可选要求。常见的预锁定条件包括要求文档处于全屏模式或属于已安装的 Web 应用。有关具体示例,请参见10. 与 Web 应用清单的交互以及9. 与全屏 API 的交互。
当以lock() 方法并传入OrientationLockType orientation 时,用户代理必须执行以下步骤。
Document。NotSupportedError”DOMException 为原因被拒绝的 Promise,并中止后续步骤。NotAllowedError”DOMException 为原因被拒绝的 Promise,并中止后续步骤。[[orientationPendingPromise]] 不是 null,则拒绝并置空当前锁定 Promise,并使用“AbortError”。[[orientationPendingPromise]] 设为一个新 Promise。[[orientationPendingPromise]]。当调用unlock() 方法时,用户代理必须执行以下步骤。
Document。null,返回 undefined。[[orientationPendingPromise]] 不是 null,则拒绝并置空当前锁定 Promise,并使用“AbortError”。null 到 document。对Document document 的常见安全检查包括以下步骤:
InvalidStateError”DOMException。SecurityError”DOMException。SecurityError”DOMException。获取 angle 属性时,返回this 的[[angle]]。
The onchange attribute is an event handler IDL attribute for the onchange event handler, whose event handler event type is change.
WebIDLenum OrientationLockType {
"any",
"natural",
"landscape",
"portrait",
"portrait-primary",
"portrait-secondary",
"landscape-primary",
"landscape-secondary"
};
OrientationLockType 枚举表示屏幕可能被锁定的方向。
WebIDLenum OrientationType {
"portrait-primary",
"portrait-secondary",
"landscape-primary",
"landscape-secondary"
};
OrientationType 枚举值用于表示屏幕的当前方向类型。
当创建一个浏览上下文 context 时,用户代理必须
ScreenOrientation。[[initialType]] 内部槽位为屏幕的当前方向类型。[[type]] 内部槽位为屏幕的当前方向类型。[[angle]] 内部槽位为屏幕的当前方向角度。当步骤需要拒绝并置空当前锁定 Promise(对应Document document)并提供DOMString exceptionName 时,用户代理必须
[[orientationPendingPromise]] 不是 null。[[orientationPendingPromise]]。DOMException。[[orientationPendingPromise]] 设为 null。当步骤要求 应用方向锁定 OrientationLockType? orientation 于 Document document 时,用户代理 必须 执行以下步骤
[[orientationPendingPromise]] 不为 null,则 拒绝并清空当前锁定 Promise(对 document)并使用 “AbortError”。[[orientationPendingPromise]] 为 null,则继续。AbortError”。[[orientationPendingPromise]] 不为 null,则 拒绝并清空当前锁定 Promise(对 document),使用 “AbortError”,并中止本步骤。null,则 解锁屏幕方向。null。[[orientationPendingPromise]] 不为 null,则 拒绝并清空当前锁定 Promise(对 document),并使用 “NotSupportedError”。这可能发生在用户设置了阻止网页应用改变屏幕方向的偏好,或底层平台(而非用户代理)不允许将屏幕方向锁定到给定的 orientation 时。请注意,用户偏好或平台能力的差异可能被用于指纹识别,因为它们可能在锁定失败行为上形成可检测的模式。
[[orientationPendingPromise]]。[[orientationPendingPromise]] 设为 null。null,则 解析 promise 为 undefined。当用户代理判断屏幕方向已为 顶层可遍历对象 更改,或用户将 顶层浏览上下文 移动到其他屏幕时,则对该 顶层可遍历对象 的 活跃文档 运行 屏幕方向更改步骤。
屏幕方向更改步骤 对 Document document 如下
ScreenOrientation。[[type]],且 angle 等于 screenOrientation 的 [[angle]],则中止本步骤。[HTML]的 “更新可见性状态” 算法会运行 屏幕方向更改步骤。
每当 卸载文档清理步骤 对 document 运行时,用户代理 必须 运行以下步骤
完全解锁屏幕方向步骤 对 Document document 如下
[[orientationPendingPromise]] 不为 null,则 拒绝并清空当前锁定 Promise(对 document),并使用 “AbortError”。null 于 topDocument。用户代理 必须 将 lock() 的使用限制在简单全屏文档上,作为 预锁定条件。此要求防止通过用户代理在方向锁定权限上的行为差异进行指纹识别。[fullscreen]
当 文档 退出全屏时,它也会运行 完全解锁屏幕方向步骤。[fullscreen]
Web Application Manifest 规范允许 Web 应用通过 orientation 成员设置 默认屏幕方向。
用户代理 应该 要求 已安装的 Web 应用 以 “全屏” display mode 呈现,作为 预锁定条件。
由于用户可能将设备固定在某个方向(例如安装在轮椅扶手上),在 锁定屏幕方向 时期望用户旋转设备的开发者,需要了解 Web Content Accessibility Guidelines (WCAG) 2.1 的 方向成功准则。该准则使得无论 屏幕方向 如何,内容和功能都必须可用。当特定方向为 必要 时,Web 应用必须提醒用户该方向要求。
屏幕的 类型 与 角度 是潜在的指纹识别向量。以下缓解措施有助于保护用户隐私,不泄露设备的持握方式,同时防止 次要 方向类型及其关联角度被用于指纹识别。
为保护用户隐私,方向更改事件受到多项投递限制。
对 文档 必须是 具有用户注意的顶层可遍历对象的完全激活后代 的要求,确保方向事件仅投递到系统层面可见且拥有用户注意(通过焦点或能够接收键盘输入)的窗口。额外的可见性状态检查提供了深度防御。这些限制防止后台标签页、隐藏窗口以及最小化的应用收集方向数据用于指纹识别。
为抵抗指纹识别,用户代理 应该 实施以下保护,尤其在私人浏览等注重隐私的情境下。
[[initialType]]。type 获取器的返回值,仅为 “portrait-primary” 或 “landscape-primary”。屏幕宽高比决定返回哪一个。[[initialType]] 相同,则对 angle 获取器返回 0。否则返回 90。除了标记为非规范性的章节外,本规范中的所有创作指南、图表、示例和注释均为非规范性内容。本规范中的其他所有内容均为规范性内容。
本文档中的关键字 MAY、MUST 与 SHOULD 应按照 BCP 14 [RFC2119] [RFC8174] 的定义进行解释,仅当它们全部大写出现时(如本处所示)。
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.[[angle]] internal slot for ScreenOrientation §5.1"any" enum value for OrientationLockType §6.[[initialType]] internal slot for ScreenOrientation §5.1"landscape" enum value for OrientationLockType §6.lock method for ScreenOrientation §5."natural" enum value for OrientationLockType §6.onchange attribute for ScreenOrientation §5.orientation attribute for Screen §4.OrientationLockType enum §6.[[orientationPendingPromise]] internal slot for Document §3.1OrientationType enum §7."portrait" enum value for OrientationLockType §6.ScreenOrientation interface §5.type attribute for ScreenOrientation §5.[[type]] internal slot for ScreenOrientation §5.1unlock method for ScreenOrientation §5.manifest)
Screen interface
Document 接口
EventTarget 接口
Document)
EventHandler
Document)
Document)
Document)
Window 接口
list)
AbortError 异常
DOMException 接口
DOMString 接口
[Exposed] 扩展属性
InvalidStateError 异常
NotAllowedError 异常
NotSupportedError 异常
Promise 接口
[SameObject] 扩展属性
SecurityError exception
exception)
undefined 类型
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.
引用自
引用自
引用自
引用自
引用自
引用自
引用自
引用自
引用自
引用自
引用自
引用自
引用自
引用自
引用自
引用自
引用自
引用自