屏幕方向

W3C工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2025/WD-screen-orientation-20251021/
最新发布版本:
https://www.w3.org/TR/screen-orientation/
最新编辑草案:
https://w3c.github.io/screen-orientation/
历史记录:
https://www.w3.org/standards/history/screen-orientation/
提交历史
测试套件:
https://wpt.live/screen-orientation/
编辑:
Marcos Cáceres (Apple公司)
前任编辑:
Mounir Lamouri (Google公司)
Johanna Herman (受邀专家)
反馈:
GitHub w3c/screen-orientation (拉取请求新问题开放问题)
浏览器支持:
caniuse.com

摘要

屏幕方向规范对设备屏幕方向的类型和角度进行了标准化,并提供了 锁定和解锁的方法。该规范定义的 API 会公开设备当前的 屏幕方向类型和角度,并在其变化时分派事件。这使得 Web 应用能够与 CSS 配合,以编程方式为 多种屏幕方向调整用户体验。该 API 尤其适用于诸如电脑游戏之类的应用, 在这类应用中,用户会物理地旋转设备,但屏幕方向本身 不应改变。该 API 对锁定屏幕方向进行了限制, 只有在满足某些 预锁定条件 时才允许。

本文档状态

本节描述了本文档在发布时的状态。最新的 W3C 发布列表及本技术报告的最新修订版可在 W3C 标准与草案索引中找到。

本文档仍在持续完善中。

本文档由 Web Applications Working Group 作为工作草案通过 推荐流程发布。

作为工作草案发布,并不代表 W3C 及其成员的认可。

本文档为草案,可能随时被更新、替换或废弃。除作为在研工作外,不适宜引用本文件。

本文档由遵循 W3C 专利政策 的工作组编制。 W3C 维护了 与本组成果相关的专利披露公开列表, 该页面还包括专利披露指引。任何个人若确知某项专利包含 必要声明, 必须按 W3C 专利政策第 6 节 披露相关信息。

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

1. 使用示例

本节为非规范性内容。

在此示例中,选择“锁定”按钮会请求进入 全屏模式,然后将屏幕锁定为相反的方向。 选择“解锁”按钮会解锁屏幕。

示例 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">
  锁定到...
</button>
<button onclick="screen.orientation.unlock()">
  解锁
</button>

2. 概念

锁定屏幕方向到某个 OrientationLockType orientation 意味着用户只能将屏幕旋转到特定的 屏幕方向 —— 可能会排除其他方向。屏幕可旋转到的方向由用户代理、用户偏好、操作系统的惯例或屏幕本身决定。例如, 将方向锁定为 landscape 意味着用户可以将屏幕旋转到 landscape-primary,如果系统允许,也许还能旋转到 landscape-secondary,但不会变为 portrait-secondary 方向。

解锁屏幕方向后,最终用户可以不受限制地将屏幕旋转到系统允许的任何 屏幕方向

2.1 屏幕方向类型

屏幕可以处于,或锁定为下列之一的 屏幕方向

任意
用户可以将屏幕旋转到设备操作系统或最终用户允许的任意方向。
默认(未锁定)
当屏幕未锁定时,设备的默认行为 (即活动方向锁定null)。该方向由设备的操作系统、用户代理、最终用户控制,或可能由 已安装的 Web 应用设置。例如, 当屏幕方向未锁定且用户旋转设备时,某些设备会将方向变化限制为 portrait-primarylandscape-primarylandscape-secondary, 但不会变为 portrait-secondary
横屏
屏幕的宽度大于高度。
自然
设备显示屏最自然的方向,由用户代理、用户、操作系统或屏幕本身决定。例如,设备面向用户时被直立持握。电脑显示器通常的自然方向为 landscape-primary,而手机通常的自然方向为 portrait-primary
竖屏
屏幕的高度大于宽度。
主方向
设备屏幕的自然方向,可以是 竖屏横屏
次方向
设备屏幕主方向的相反方向,可以是 竖屏横屏

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 对象(即 ScreenOrientation 实例,位于 window.screen.orientation)。

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() 方法

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

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

  1. documentthis相关全局对象关联的 Document
  2. document 运行 通用安全检查。如果 异常抛出,则返回 一个以该异常被拒绝的 promise,并中止这些步骤。
  3. 如果 用户代理 不支持将屏幕方向锁定为 orientation,则返回 一个被拒绝的 promise,其原因为 "NotSupportedError" DOMException,并中止这些步骤。
  4. 如果 用户代理 要求 document 及其关联的 浏览上下文 满足 预锁定条件 才能锁定屏幕方向,且这些条件未被满足, 则返回 一个被拒绝的 promise,其原因为 "NotAllowedError" DOMException,并中止这些步骤。
  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,则对 document当前锁定 promise 进行拒绝并置为 null,异常为 "AbortError"。
  5. 应用方向锁定 nulldocument
注意:为什么 unlock() 不返回 promise?

unlock() 不返回 promise,因为它等价于锁定到 默认屏幕方向,而该方向可能会或者不会被 用户代理知晓。因此,用户代理 无法预测新的方向会是什么,甚至无法预测是否会发生方向变化。

5.4 常见安全检查

通用安全检查针对 Document document 的步骤如下:

  1. 如果 document 不是 具有用户注意的顶层可遍历项的完全激活后代抛出 "InvalidStateError" DOMException
  2. 如果 document 设置了 沙箱化的方向锁定浏览上下文标志抛出 "SecurityError" DOMException
  3. 如果 document可见性状态 为 "hidden",抛出 "SecurityError" DOMException

5.5 type 属性

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

5.6 angle 属性

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

注意:angle 的取值代表什么?

5.7 onchange 事件处理程序属性

onchange 属性是一个 事件处理程序 IDL 属性, 用于 onchange 事件处理程序,其 事件处理类型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. screenOrientation成为context关联的ScreenOrientation
  2. 初始化screenOrientation[[initialType]]内部槽为屏幕的当前方向类型
  3. 初始化screenOrientation[[type]]内部槽为屏幕的当前方向类型
  4. 初始化screenOrientation[[angle]]内部槽为屏幕的当前方向角度

8.2 拒绝文档的当前锁定承诺

当步骤要求用 DOMString exceptionNameDocument document当前锁定 promise 进行拒绝并置为 null 时, 用户代理必须

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

8.3 应用屏幕方向锁定

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

  1. 如果 document并行执行过程中停止为 完全激活, 且 [[orientationPendingPromise]] 不为 null,则 拒绝并清空当前锁定的 promise,原因为 "AbortError"。
  2. topDocumentdocument顶层可遍历项活动文档
  3. descendantDocs有序集合,内容包括 topDocument后代 navigables活动文档,若有,如树型顺序。
  4. 对每个 docdescendantDocs 中执行:
    1. docdocument,跳过。
    2. doc[[orientationPendingPromise]]null,跳过。
    3. 拒绝并清空当前锁定的 promise,原因为 "AbortError"。
  5. 以下子步骤并行执行:
    1. document 已停止为 完全激活, 且 document[[orientationPendingPromise]] 不为 null,则 拒绝并清空当前锁定的 promise, 原因为 "AbortError",并中止这些步骤。
    2. orientationnull解锁屏幕方向
    3. 否则,尝试 锁定屏幕方向orientation。 可根据平台约定修改视口绘制方式以匹配 orientation
    4. 若因用户先前设定偏好、平台限制或其它原因导致尝试失败:
      1. 将屏幕的活动方向锁定 置为 null
      2. 加入任务队列DOM 操作任务源, 使用 document相关全局对象来执行:
        1. document[[orientationPendingPromise]] 不为 null拒绝并清空当前锁定的 promise, 原因为 "NotSupportedError"。
        2. 中止这些步骤。

      当用户设置了阻止 Web 应用更改屏幕方向的偏好,或底层平台(而非用户代理)不允许锁定指定的 orientation 时可能发生以上情况。需注意,用户偏好或平台能力的差异可能会被用于指纹识别,因为它们可能导致锁定失败出现可检测模式。

    5. 将屏幕的活动方向锁定 设为 orientation,并根据需要更新当前方向类型当前方向角度, 以反映 屏幕方向的任何变化。
  6. 加入全局任务队列DOM 操作任务源, 使用 document相关全局对象来执行:
    1. promisedocument[[orientationPendingPromise]]
    2. document[[orientationPendingPromise]] 设为 null
    3. topDocument 执行 屏幕方向变更步骤
    4. promise 不为 nullundefined 解析 promise

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后代 navigables活动文档(如有),按树型顺序排列。
  7. 依次descendantDocs 中的 doc, 执行 屏幕方向变更步骤,目标为 doc

8.5 处理页面可见性更改

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

8.6 处理卸载文档

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

  1. 如果 document 不是 顶层可遍历项活动文档,则中止这些步骤。
  2. document 执行 完全解锁屏幕方向步骤

8.7 完全解锁方向

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

  1. 如果 document[[orientationPendingPromise]] 不为 null,则 拒绝并清空当前锁定 promise, 原因为 "AbortError"。
  2. topDocumentdocument顶层可遍历项活动文档
  3. 应用方向锁 nulltopDocument

9. 与全屏 API 的交互

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

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

10. 与 Web 应用清单的交互

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

用户代理应当要求已安装的 Web 应用以 "fullscreen" 显示模式展示,作为锁定前置条件

11. 可访问性考虑

由于用户的设备可能固定在一个方向上(例如安装在轮椅的扶手上),当开发人员希望用户在锁定屏幕方向时旋转设备时,开发人员需要了解Web 内容无障碍指南 (WCAG) 2.1中的方向成功标准。该标准要求无论屏幕方向如何,内容和功能必须可用。如果特定方向是必需的,Web 应用必须告知用户方向要求。

12. 隐私和安全考虑

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

12.1 事件传递限制

为保护用户隐私,方向变更事件的传递受到多项限制:

文档 要求是 具有用户注意的顶层可遍历项的完全激活后代 ,确保方向事件仅发送到既在系统层面可见又获得用户关注(如有焦点或能接受键盘输入)的窗口中的文档。额外的可见性状态检查进一步增强安全性。这些限制可防止后台标签页、隐藏窗口和最小化应用收集方向数据以进行指纹识别。

12.2 反指纹识别缓解措施

为了抵御指纹识别,用户代理SHOULD实施以下保护措施,特别是在注重隐私的环境如隐私浏览模式下:

  1. 顶层可遍历项的整个生命周期内, 始终表现为屏幕的 自然 方向即 [[initialType]]
  2. type getter 的可能返回值限制为 "portrait-primary" 或 "landscape-primary"。 返回值由屏幕宽高比决定。
  3. 如果 当前方向类型[[initialType]] 相同,则 angle getter 返回 0,否则返回 90
  4. 屏幕方向改变时,仅当 当前方向类型竖屏 切换到 横屏或反向切换时,才触发 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. 致谢

感谢 Christophe Dumez、Anne van Kesteren、Chundong Wang、Fuqiao Xue 和 Chaals McCathie Nevile 提出的有用意见。

特别感谢 Chris Jones 和 Jonas Sicking 对该 API 最初设计的贡献。

D. 参考文献

D.1 规范性引用

[appmanifest]
Web 应用清单(Web Application Manifest)。Marcos Caceres;Kenneth Christiansen;Diego Gonzalez-Zuniga;Daniel Murphy;Christian Liebel。W3C。2025年9月3日。W3C 工作草案。网址:https://www.w3.org/TR/appmanifest/
[cssom-view]
CSSOM 视图模块(CSSOM View Module)。Simon Fraser; Emilio Cobos Álvarez。W3C。2025年9月16日。W3C 工作草案。网址:https://www.w3.org/TR/cssom-view-1/
[dom]
DOM 标准(DOM Standard)。Anne van Kesteren。WHATWG。 实时标准。网址:https://dom.spec.whatwg.org/
[fullscreen]
全屏 API 标准(Fullscreen API Standard)。Philip Jägenstedt。WHATWG。实时标准。网址:https://fullscreen.spec.whatwg.org/
[HTML]
HTML 标准(HTML Standard)。Anne van Kesteren; Domenic Denicola;Dominic Farolino;Ian Hickson;Philip Jägenstedt;Simon Pieters。WHATWG。实时标准。网址:https://html.spec.whatwg.org/multipage/
[infra]
基础设施标准(Infra Standard)。Anne van Kesteren;Domenic Denicola。WHATWG。实时标准。网址:https://infra.spec.whatwg.org/
[mediaqueries-5]
媒体查询5级(Media Queries Level 5)。Dean Jackson;Florian Rivoal;Tab Atkins Jr.;Daniel Libby。W3C。2021年12月18日。W3C 工作草案。网址:https://www.w3.org/TR/mediaqueries-5/
[RFC2119]
用于 RFC 中指示需求级别的关键词(Key words for use in RFCs to Indicate Requirement Levels)。S. Bradner。IETF。1997年3月。最佳现行规范。网址:https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119 关键词大小写歧义(Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words)。B. Leiba。IETF。2017年5月。最佳现行规范。网址:https://www.rfc-editor.org/rfc/rfc8174
[WCAG21]
网页内容无障碍指南(WCAG)2.1(Web Content Accessibility Guidelines (WCAG) 2.1)。Michael Cooper;Andrew Kirkpatrick;Joshue O'Connor;Alastair Campbell。W3C。 2025年5月6日。W3C 推荐标准。网址:https://www.w3.org/TR/WCAG21/
[WEBIDL]
Web IDL 标准(Web IDL Standard)。Edgar Chen;Timothy Gu。 WHATWG。实时标准。网址:https://webidl.spec.whatwg.org/