屏幕方向

W3C工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2026/WD-screen-orientation-20260806/
最新发布版本:
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 Inc.)
Léonie Watson(TetraLogical)
前任编辑:
Mounir Lamouri(Google Inc.)
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-primary、 landscape-primary 和 landscape-secondary, 而不包括 portrait-secondary。
横向
屏幕宽高比中的宽度大于高度。
自然
设备显示屏的参考方向,方向角度以此为基准 进行测量,该方向由用户代理、 用户、操作系统或屏幕本身确定。例如, 计算机显示器的参考方向通常为 landscape-primary,而移动 电话的参考方向通常为 portrait-primary。
注

用户代理如何确定自然方向由实现定义, 并且因平台而异。某些用户代理 对每种设备类别使用固定方向(例如, 手持设备使用 portrait-primary,而landscape-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, 它是 Screen 的 orientation 对象(即 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. 令 document 为 this 的 相关全局对象的 关联的 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. 应用方向锁 orientation 到 document。
  8. 返回 document 的 [[orientationPendingPromise]]。

5.3 unlock() 方法

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

  1. 令 document 为 this 的 相关全局对象的 关联 Document。
  2. 对 document 运行通用安全检查。如果异常被抛出,则重新抛出该异常并中止这些步骤。
  3. 如果屏幕的当前激活的方向锁定为 null,则返回 undefined。
  4. 如果 document 的 [[orientationPendingPromise]] 不为 null,则对 document 的当前锁定 promise 进行拒绝并置为 null,异常为 "AbortError"。
  5. 应用方向锁定 null 到 document。
注意:为什么 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 exceptionName 对 Document document 的 当前锁定 promise 进行拒绝并置为 null 时, 用户代理必须:

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

8.3 应用屏幕方向锁定

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

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

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

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

8.4 屏幕方向更改

当用户代理判断某个顶层可遍历项的屏幕方向发生了变化, 或者用户将顶层浏览上下文移动到不同屏幕时, 应对该执行屏幕方向变更步骤, 目标是该顶层可遍历项的 活动文档。

屏幕方向变更步骤针对 Document document,具体如下:

  1. 如果 document 不是 具有用户注意的顶层可遍历项的完全激活后代,则中止这些步骤。
  2. 令 type 和 angle 为屏幕的 当前方向类型 和 当前方向角度。
  3. 令 screenOrientation 为 document 的 相关全局对象的 关联的 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. 令 topDocument 为 document 的 顶层可遍历项的 活动文档。
  3. 应用方向锁 null 到 topDocument。

9. 与全屏 API 的交互

用户代理MUST将 lock() 的使用限制为 简单全屏文档,作为预锁定条件。此要求可防止通过用户代理在方向锁定权限方面的行为差异进行指纹识别。 [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. 一致性

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

本文档中的关键词 MAY、MUST 和 SHOULD 应按照 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 应用清单。Marcos Caceres;Daniel Murphy;Christian Liebel。W3C。2026 年 7 月 23 日。W3C 工作草案。URL:https://www.w3.org/TR/appmanifest/
[cssom-view]
CSSOM 视图模块。Simon Fraser; Emilio Cobos Álvarez。W3C。2025 年 9 月 16 日。W3C 工作草案。URL:https://www.w3.org/TR/cssom-view-1/
[dom]
DOM 标准。Anne van Kesteren。WHATWG。 现行标准。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.spec.whatwg.org/multipage/
[infra]
Infra 标准。Anne van Kesteren;Domenic Denicola。WHATWG。现行标准。URL:https://infra.spec.whatwg.org/
[RFC2119]
用于在 RFC 中指示 要求级别的关键词。S. Bradner。IETF。1997 年 3 月。最佳当前实践。URL:https://www.rfc-editor.org/info/rfc2119/
[RFC8174]
RFC 2119 关键词中大写与小写的歧义。B. Leiba。IETF。2017 年 5 月。最佳当前实践。URL:https://www.rfc-editor.org/info/rfc8174/
[WCAG21]
Web 内容无障碍指南(WCAG) 2.1。Michael Cooper;Andrew Kirkpatrick;Joshue O'Connor;Alastair Campbell。W3C。 2025 年 5 月 6 日。W3C 推荐标准。URL:https://www.w3.org/TR/WCAG21/
[WEBIDL]
Web IDL 标准。Edgar Chen;Timothy Gu。 WHATWG。现行标准。URL:https://webidl.spec.whatwg.org/