屏幕方向

W3C 工作草案

关于此文档的更多细节
此版本
https://w3org.cn/TR/2025/WD-screen-orientation-20251021/
最新发布版本
https://w3org.cn/TR/screen-orientation/
最新编辑草案
https://w3c.github.io/screen-orientation/
历史
https://w3org.cn/standards/history/screen-orientation/
提交历史
测试套件
https://wpt.live/screen-orientation/
编辑
Marcos Cáceres (Apple Inc.)
前任编辑
Mounir Lamouri (Google Inc.)
Johanna Herman (Invited Expert)
反馈
GitHub w3c/screen-orientation (pull requests, new issue, open issues)
浏览器支持
caniuse.com

摘要

Screen Orientation 规范统一了设备屏幕方向的类型和角度,并提供了锁定与解锁的手段。该规范定义的 API 暴露了设备屏幕方向的当前类型和角度,并在方向变化时分发事件。这使得 Web 应用能够以编程方式适配多种屏幕方向,并可配合 CSS 使用。该 API 对于如电脑游戏等场景尤为有用——用户会实际旋转设备,但屏幕方向本身不应随之改变。只有在满足特定的预锁定条件时,API 才会限制锁定屏幕方向。

本文档状态

本节描述了本文件发布时的状态。当前的 W3C 出版物列表和本技术报告的最新版本可以在 W3C 标准和草案索引中找到。

本文件仍在持续完善中。

本文档由 Web 应用程序工作组发布,作为一份使用推荐标准轨道的工作草案。

发布为工作草案并不意味着 W3C 及其成员的认可。

这是一份草案文件,可能随时被其他文件更新、替换或废弃。将其作为进展中的工作以外的引用是不恰当的。

本文档由在一个受 W3C 专利政策 约束下运营的组织所编写。W3C 维护了一份 与该工作组交付成果相关的专利披露公开列表;该页面还包含披露专利的说明。任何知晓其认为包含 必要权利要求 的专利的个人,必须按照 W3C 专利政策第 6 节 的规定披露相关信息。

本文件受 2025 年 8 月 18 日 W3C 流程文档约束。

1. 使用示例

本节是非规范性的。

在本示例中,点击 “Lock” 按钮会请求进入全屏并将屏幕锁定到相反的方向。点击 “Unlock” 按钮则解锁屏幕。

示例 1:锁定到特定方向并解锁
<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. 概念

锁定屏幕方向OrientationLockType orientation,意味着用户只能将屏幕旋转到特定的屏幕方向——可能会排除其他方向。可以旋转到的方向由用户代理、用户偏好、操作系统约定或屏幕本身决定。例如,将方向锁定为横向,则用户可以将屏幕旋转到横向主方向,并在系统允许的情况下可能兼容横向次方向,但不会切换到纵向次方向

解锁屏幕方向,最终用户可以自由将屏幕旋转到系统允许的任何屏幕方向

2.1 屏幕方向类型

屏幕可以处于以下锁定状态之一的屏幕方向

任意
用户可以将屏幕旋转到设备操作系统或最终用户允许的任何方向。
默认(未锁定)
当屏幕未锁定时(即活动方向锁定null),设备的默认行为。此方向由操作系统、用户代理、最终用户或可能由已安装的 Web 应用设定。例如,当屏幕未锁定且用户旋转设备时,有些设备仅会在纵向主方向横向主方向横向次方向之间切换,而不会切换到纵向次方向
横向
屏幕宽度大于高度的比例。
自然
由用户代理、用户、操作系统或屏幕本身决定的设备显示的最自然方向。例如,设备竖直握持、屏幕面向用户时的方向。电脑显示器通常自然横向主方向,而移动电话通常自然纵向主方向
纵向
屏幕高度大于宽度的比例。
主方向
设备屏幕的自然方向,可为纵向横向
次方向
设备屏幕主方向的相反方向,可为纵向横向

2.2 当前屏幕方向类型与角度

输出设备的屏幕具有以下关联概念

活动方向锁定
表示屏幕当前的屏幕方向,用OrientationLockType 表示;在锁定时有值,否则为 null未锁定)。
当前方向角度
屏幕相对于其自然方向逆时针旋转的度数,取自屏幕方向值列表
当前方向类型
屏幕的屏幕方向,用OrientationType 枚举值表示。

下面的屏幕方向值列表标准化了不同自然方向的屏幕上,各方向类型对应的角度。

对于自然纵向方向的屏幕
对于自然横向方向的屏幕

3. Document 接口的扩展

3.1 内部槽位

Document 接口被扩展了以下内部槽位

内部槽 描述
[[orientationPendingPromise]] 要么为 null,要么为Promise。当被赋值为Promise时,该 Promise 代表对锁定屏幕方向的请求。

4. Screen 接口的扩展

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

Window 对象拥有一个关联的 ScreenOrientation,即Screenorientation 对象(即 window.screen.orientation 处的ScreenOrientation 实例)。

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

5.1 内部槽位

内部槽 描述
[[angle]] 表示屏幕最近一次记录的当前方向角度(单位:度),以unsigned short 表示,取自屏幕方向值列表
[[initialType]] 表示在创建浏览上下文时,屏幕的当前方向类型
[[type]] 表示屏幕最近一次记录的当前方向类型,以OrientationType 枚举值表示。

5.2 lock() 方法

预锁定条件是用户代理在允许屏幕方向锁定前可能施加的可选要求。常见的预锁定条件包括要求文档处于全屏模式或属于已安装的 Web 应用。有关具体示例,请参见10. 与 Web 应用清单的交互以及9. 与全屏 API 的交互

当以lock() 方法并传入OrientationLockType orientation 时,用户代理必须执行以下步骤。

  1. documentthis相关全局对象关联 Document
  2. document 运行常见安全检查。如果抛出异常,返回一个以该异常被拒绝的 Promise并中止后续步骤。
  3. 如果用户代理不支持将屏幕方向锁定为 orientation,返回一个以NotSupportedErrorDOMException 为原因被拒绝的 Promise,并中止后续步骤。
  4. 如果用户代理要求 document 以及其关联的浏览上下文满足预锁定条件才能锁定屏幕方向,且这些条件未满足,则返回一个以NotAllowedErrorDOMException 为原因被拒绝的 Promise,并中止后续步骤。
  5. 如果 document[[orientationPendingPromise]] 不是 null,则拒绝并置空当前锁定 Promise,并使用“AbortError”。
  6. document[[orientationPendingPromise]] 设为一个新 Promise
  7. 应用方向锁定 orientationdocument
  8. 返回 document[[orientationPendingPromise]]

5.3 unlock() 方法

当调用unlock() 方法时,用户代理必须执行以下步骤。

  1. documentthis相关全局对象关联 Document
  2. document 运行常见安全检查。如果抛出异常,则重新抛出该异常并中止后续步骤。
  3. 如果屏幕的活动方向锁定null,返回 undefined
  4. 如果 document[[orientationPendingPromise]] 不是 null,则拒绝并置空当前锁定 Promise,并使用“AbortError”。
  5. 应用方向锁定 nulldocument
: 为什么 unlock() 不返回 Promise?

unlock() 不返回 Promise,因为它等价于锁定为默认屏幕方向,而该默认方向可能并不为用户代理所知。因此,用户代理无法预判新方向会是什么,甚至是否会改变。

5.4 常见安全检查

Document document常见安全检查包括以下步骤:

  1. 如果 document 不是拥有用户注意力的顶层可遍历文档的完全活跃子代,则抛出InvalidStateErrorDOMException
  2. 如果 document 设置了沙盒化方向锁定浏览上下文标志,则抛出SecurityErrorDOMException
  3. 如果 document可见性状态为“hidden”,则抛出SecurityErrorDOMException

5.5 type 属性

获取 type 属性时,返回this[[type]]

5.6 angle 属性

获取 angle 属性时,返回this[[angle]]

: angle 的取值代表什么?

5.7 onchange 事件处理属性

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

6. OrientationLockType 枚举

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

OrientationLockType 枚举表示屏幕可能被锁定的方向。

: 对方向的支持情况

7. OrientationType 枚举

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

OrientationType 枚举值用于表示屏幕的当前方向类型

8. 算法

8.1 初始化 ScreenOrientation 对象

当创建一个浏览上下文 context 时,用户代理必须

  1. screenOrientationcontext关联 ScreenOrientation
  2. 初始化 screenOrientation[[initialType]] 内部槽位为屏幕的当前方向类型
  3. 初始化 screenOrientation[[type]] 内部槽位为屏幕的当前方向类型
  4. 初始化 screenOrientation[[angle]] 内部槽位为屏幕的当前方向角度

8.2 拒绝文档当前的锁定 Promise

当步骤需要拒绝并置空当前锁定 Promise(对应Document document)并提供DOMString exceptionName 时,用户代理必须

  1. Assert[[orientationPendingPromise]] 不是 null
  2. promisedocument[[orientationPendingPromise]]
  3. 排队全局任务DOM 操作任务源 上,以 document相关全局对象 拒绝 promise,并使用新的 exceptionName DOMException
  4. document[[orientationPendingPromise]] 设为 null

8.3 应用方向锁定

当步骤要求 应用方向锁定 OrientationLockType? orientationDocument document 时,用户代理 必须 执行以下步骤

  1. 如果 document完全激活 状态结束时仍在 并行执行,且 [[orientationPendingPromise]] 不为 null,则 拒绝并清空当前锁定 Promise(对 document)并使用 “AbortError”。
  2. topDocumentdocument顶层可遍历对象活跃文档
  3. descendantDocs 为一个 有序集合,其中按树序包含 topDocument后代可遍历对象活跃文档(若存在)。
  4. 对于每个 docdescendantDocs
    1. 如果 doc 等于 document,则继续。
    2. 如果 doc[[orientationPendingPromise]]null,则继续。
    3. 拒绝并清空当前锁定 Promise(对 doc),并使用 “AbortError”。
  5. 并行执行 以下子步骤
    1. 如果 document 已停止 完全激活,且 document[[orientationPendingPromise]] 不为 null,则 拒绝并清空当前锁定 Promise(对 document),使用 “AbortError”,并中止本步骤。
    2. 如果 orientationnull,则 解锁屏幕方向
    3. 否则,尝试 锁定屏幕方向orientation。根据平台惯例,改变视口的绘制方式以匹配 orientation
    4. 如果尝试因先前已设定的用户偏好、平台限制或任何其他原因而失败
      1. 将屏幕的 活动方向锁定 设为 null
      2. 排队任务DOM 操作任务源 上,以 document相关全局对象
        1. 如果 document[[orientationPendingPromise]] 不为 null,则 拒绝并清空当前锁定 Promise(对 document),并使用 “NotSupportedError”。
        2. 中止这些步骤。

      这可能发生在用户设置了阻止网页应用改变屏幕方向的偏好,或底层平台(而非用户代理)不允许将屏幕方向锁定到给定的 orientation 时。请注意,用户偏好或平台能力的差异可能被用于指纹识别,因为它们可能在锁定失败行为上形成可检测的模式。

    5. 将屏幕的 活动方向锁定 设为 orientation,并更新 当前方向类型当前方向角度,以反映对 屏幕方向 所做的任何更改。
  6. 排队全局任务DOM 操作任务源 上,以 document相关全局对象
    1. promisedocument[[orientationPendingPromise]]
    2. document[[orientationPendingPromise]] 设为 null
    3. 运行 屏幕方向更改步骤,使用 topDocument
    4. 如果 promise 不为 null,则 解析 promiseundefined

8.4 屏幕方向变化

当用户代理判断屏幕方向已为 顶层可遍历对象 更改,或用户将 顶层浏览上下文 移动到其他屏幕时,则对该 顶层可遍历对象活跃文档 运行 屏幕方向更改步骤

屏幕方向更改步骤Document document 如下

  1. 如果 document 不是 具有用户注意的顶层可遍历对象的完全激活后代,则中止本步骤。
  2. typeangle 分别为屏幕的 当前方向类型当前方向角度
  3. screenOrientationdocument相关全局对象关联的 ScreenOrientation
  4. 如果 type 等于 screenOrientation[[type]],且 angle 等于 screenOrientation[[angle]],则中止本步骤。
  5. 排队全局任务用户交互任务源 上,以 document相关全局对象
    1. screenOrientation[[angle]] 设为 angle
    2. screenOrientation[[type]] 设为 type
    3. 触发事件,名称为 “change”,目标为 screenOrientation
  6. descendantDocs 为一个 有序集合,其中按树序包含 document后代可遍历对象活跃文档(若存在)。
  7. 对于每个 docdescendantDocs,运行 屏幕方向更改步骤,使用 doc

8.5 处理页面可见性变化

HTML]的 “更新可见性状态” 算法会运行 屏幕方向更改步骤

8.6 处理文档卸载

每当 卸载文档清理步骤document 运行时,用户代理 必须 运行以下步骤

  1. 如果 document 不是 顶层可遍历对象活跃文档,则中止本步骤。
  2. document 运行 完全解锁屏幕方向步骤

8.7 完全解锁方向

完全解锁屏幕方向步骤Document document 如下

  1. 如果 document[[orientationPendingPromise]] 不为 null,则 拒绝并清空当前锁定 Promise(对 document),并使用 “AbortError”。
  2. topDocumentdocument顶层可遍历对象活跃文档
  3. 应用方向锁定 nulltopDocument

9. 与全屏 API 的交互

用户代理 必须lock() 的使用限制在简单全屏文档上,作为 预锁定条件。此要求防止通过用户代理在方向锁定权限上的行为差异进行指纹识别。[fullscreen]

文档 退出全屏时,它也会运行 完全解锁屏幕方向步骤。[fullscreen]

10. 与 Web 应用清单的交互

Web Application Manifest 规范允许 Web 应用通过 orientation 成员设置 默认屏幕方向

用户代理 应该 要求 已安装的 Web 应用 以 “全屏” display mode 呈现,作为 预锁定条件

11. 可访问性考虑

由于用户可能将设备固定在某个方向(例如安装在轮椅扶手上),在 锁定屏幕方向 时期望用户旋转设备的开发者,需要了解 Web Content Accessibility Guidelines (WCAG) 2.1方向成功准则。该准则使得无论 屏幕方向 如何,内容和功能都必须可用。当特定方向为 必要 时,Web 应用必须提醒用户该方向要求。

12. 隐私与安全考虑

屏幕的 类型角度 是潜在的指纹识别向量。以下缓解措施有助于保护用户隐私,不泄露设备的持握方式,同时防止 次要 方向类型及其关联角度被用于指纹识别。

12.1 事件投递限制

为保护用户隐私,方向更改事件受到多项投递限制。

文档 必须是 具有用户注意的顶层可遍历对象的完全激活后代 的要求,确保方向事件仅投递到系统层面可见且拥有用户注意(通过焦点或能够接收键盘输入)的窗口。额外的可见性状态检查提供了深度防御。这些限制防止后台标签页、隐藏窗口以及最小化的应用收集方向数据用于指纹识别。

12.2 防指纹识别缓解措施

为抵抗指纹识别,用户代理 应该 实施以下保护,尤其在私人浏览等注重隐私的情境下。

  1. 在整个 顶层可遍历对象 生命周期内,表现得好像屏幕的 自然 方向为 [[initialType]]
  2. 限制 type 获取器的返回值,仅为 “portrait-primary” 或 “landscape-primary”。屏幕宽高比决定返回哪一个。
  3. 如果 当前方向类型[[initialType]] 相同,则对 angle 获取器返回 0。否则返回 90
  4. 如果屏幕方向改变,仅在 当前方向类型portrait 变为 landscape(或反之)时,才触发 change 事件。

13. 符合性

除了标记为非规范性的章节外,本规范中的所有创作指南、图表、示例和注释均为非规范性内容。本规范中的其他所有内容均为规范性内容。

本文档中的关键字 MAYMUSTSHOULD 应按照 BCP 14 [RFC2119] [RFC8174] 的定义进行解释,仅当它们全部大写出现时(如本处所示)。

A. IDL 索引

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. 索引

B.1 本规范定义的术语

B.2 引用定义的术语

C. 致谢

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. 参考文献

D.1 规范性参考文献

[appmanifest]
Web 应用清单. Marcos Caceres; Kenneth Christiansen; Diego Gonzalez-Zuniga; Daniel Murphy; Christian Liebel. W3C. 2025年9月3日. W3C 工作草案. URL: https://w3org.cn/TR/appmanifest/
[cssom-view]
CSSOM 视图模块. Simon Fraser; Emilio Cobos Álvarez. W3C. 2025年9月16日. W3C 工作草案. URL: https://w3org.cn/TR/cssom-view-1/
[dom]
DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[fullscreen]
全屏 API 标准. Philip Jägenstedt. WHATWG. 活标准. URL: https://fullscreen.spec.whatwg.org/
[HTML]
HTML 标准. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 活标准. URL: https://html.whatwg.cn/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://w3org.cn/TR/mediaqueries-5/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. 1997年3月. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119 关键词中大小写的歧义. B. Leiba. IETF. 2017年5月. 最佳当前实践. URL: https://www.rfc-editor.org/rfc/rfc8174
[WCAG21]
Web 内容无障碍指南 (WCAG) 2.1. Michael Cooper; Andrew Kirkpatrick; Joshue O'Connor; Alastair Campbell. W3C. 6 May 2025. W3C Recommendation. URL: https://w3org.cn/TR/WCAG21/
[WEBIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/