画面の向き

W3C 作業草案

この文書の詳細
この版:
https://www.w3.org/TR/2023/WD-screen-orientation-20230809/
最新の公開版:
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.)
前編集者:
Mounir Lamouri (Google Inc.)
Johanna Herman (招待専門家)
フィードバック:
GitHub w3c/screen-orientation (プルリクエスト, 新しい Issue, オープンな Issue)
ブラウザのサポート:
caniuse.com

概要

The 画面の向き 仕様は、デバイスの画面の向きの種類と角度を標準化し、それをロックおよびロック解除する手段を提供します。 この仕様で定義された API は、デバイスの画面の向きの現在の種類と角度を公開し、変更時にイベントを発行します。これにより、Web アプリケーションは CSS と連携して複数の画面の向きに合わせてユーザー体験をプログラム的に適応させることができます。API はまた、特定の前提条件の下で画面の向きをロックすることも可能にします。これは、ユーザーが物理的にデバイスを回転させても画面の向き自体は変えたくないコンピュータゲームのようなアプリケーションで特に有用です。

この文書の状態

この節は、この文書が公開された時点での文書の状態を説明します。現在の W3C 技術報告インデックス に、現在の W3C 出版物の一覧とこの技術報告の最新改訂版が掲載されています(https://www.w3.org/TR/)。

この文書は作業中です。

この文書は Web Applications Working Group により、Recommendation track を用いて Working Draft として公開されました。

作業草案としての公開は、W3C およびそのメンバーによる支持を意味するものではありません。

これはドラフト文書であり、いつでも更新、置換、または他の文書により廃止される可能性があります。本書を作業中の文書以外のものとして引用するのは適切ではありません。

この文書は、W3C 特許ポリシー の下で運営されるグループによって作成されました。 W3C は、グループの成果物に関連して行われたあらゆる特許開示の 公開リスト を管理しています。該当ページには特許の開示手順も記載されています。実際に特許を知っており、その特許が Essential Claim(s) を含むと信じる個人は、W3C 特許ポリシー第6節 に従って情報を開示しなければなりません。

この文書は、2023年6月12日 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. 概念

画面の向きをロックするとは、OrientationLockTypeorientation にロックすることで、ユーザーが画面を特定の画面の向き にのみ回転できることを意味します — 場合によっては他の向きが除外されます。画面が回転可能な向きは、ユーザーエージェント、ユーザーの設定、オペレーティングシステムの慣習、または画面自体によって決定されます。例えば、向きを landscape にロックすると、システムが許す場合はユーザーが landscape-primary および場合によっては landscape-secondary に回転できても、画面は portrait-secondary に変更されることはありません。

画面の向きのロックを解除するとは、エンドユーザーがシステムが許容する任意の画面の向き に制限なく回転できることを意味します。

2.1 画面の向きの種類

画面は、次のいずれかの 画面の向き にある、またはロックされることがあります:

任意
画面は、デバイスのオペレーティングシステムやエンドユーザーが許可する任意の向きへユーザーによって回転させることができます。
既定の画面の向き (ロック解除)
画面がロック解除されているときのデバイスの既定の挙動(つまり、アクティブな向きのロックnull である状態)。この向きはデバイスのオペレーティングシステム、またはユーザーエージェント、エンドユーザーによって制御されるか、あるいはインストールされたウェブアプリケーション によって設定されることがあります。例えば、画面の向きがロック解除されていてユーザーがデバイスを回転させた場合、一部のデバイスは向きの変更を portrait-primarylandscape-primary、および landscape-secondary に制限し、portrait-secondary にはしないことがあります。
Landscape
画面のアスペクト比が幅が高さより大きい状態。
Natural
ユーザーエージェント、ユーザー、オペレーティングシステム、または画面自体によって決定される、デバイス表示の最も自然な向き。例えば、ユーザーが手に持って画面がユーザーに向いている状態での向き。コンピュータモニターは一般に自然に landscape-primary であることが多く、携帯電話は一般に自然に portrait-primary であることが多いです。
Portrait
画面のアスペクト比が高さが幅より大きい状態。
Primary
デバイスの画面の 自然な 向きが、portraitlandscape のいずれかであること。
Secondary
デバイスの画面の primary 向きの反対側である、portrait または landscape の向き。

2.2 現在の画面の向きの種類と角度

出力デバイスの画面には、次の関連する概念があります:

アクティブな向きのロック
画面がロックされている 画面の向き を、OrientationLockType として表したもの、または ロック解除 時の null
現在の向きの角度
画面がその 自然な 向きから反時計回りに回転している角度(度数)で、画面の向きの値リスト に基づいて導出されます。
現在の向きの種類
画面の 画面の向き を、OrientationType として表したもの。

以下の 画面の向きの値リスト は、異なる 自然な 向きを持つ画面における各画面の向き種類に関連付けられる角度を標準化します:

自然な portrait 向きの画面の場合:
自然な landscape 向きの画面の場合:

3. Document インターフェースへの拡張

3.1 内部スロット

Document インターフェースは、次の内部スロットで拡張されます:

Internal Slot Description
[[orientationPendingPromise]] 値は null または 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 内部スロット

Internal Slot Description
[[angle]] 現在の向きの角度(度)としての、画面の最後に知られている値を、unsigned short で表します。これは 画面の向きの値リスト に基づいて導出されます。
[[initialType]] ブラウジングコンテキストが作成されたときの画面の 現在の向きの種類 を表します。
[[type]] 画面の最後に知られている 現在の向きの種類 を、OrientationType 列挙値として表します。

5.2 lock() メソッド

lock() メソッドが OrientationLockTypeorientation で呼び出されると、ユーザーエージェントは次の手順を実行する MUST です。

ユーザーエージェントは、画面の向きをロックするために、ドキュメントおよびその関連するブラウジングコンテキストが1つ以上の 事前条件 を満たすことを要求することが MAY あります。詳細は 10. Interaction with Web Application Manifest および 9. Interaction with Fullscreen API を参照してください。

  1. Let document be thisrelevant global objectassociated Document とします。
  2. 共通の安全チェックdocument を使って実行します。もし例外がスローされた場合、その例外で拒否されたプロミスを返し、これらの手順を中止します。
  3. もしユーザーエージェントが orientation に画面の向きをロックすることをサポートしていない場合、"NotSupportedError" の DOMException で拒否されたプロミスを返し、これらの手順を中止します。
  4. もし document[[orientationPendingPromise]]null でない場合、現在のロックプロミスを拒否して null にする ことにより document のプロミスを "AbortError" で拒否します。
  5. document[[orientationPendingPromise]] を新しいプロミスに設定します。
  6. Apply orientation lock orientationdocument に適用します。
  7. document[[orientationPendingPromise]] を返します。

5.3 unlock() メソッド

unlock() メソッドが呼び出されると、ユーザーエージェントは次の手順を実行する MUST です:

  1. Let document be thisrelevant global objectassociated Document とします。
  2. 共通の安全チェックdocument で実行します。もし例外がスローされた場合、その例外を再スローし、手順を中止します。
  3. もしスクリーンの アクティブな向きのロックnull であれば undefined を返します。
  4. もし document[[orientationPendingPromise]]null でない場合、現在のロックプロミスを拒否して null にする ことにより document のプロミスを "AbortError" で拒否します。
  5. Apply orientation locknull にして document に適用します。
Note: Why does unlock() not return a promise?

unlock() がプロミスを返さないのは、これは既定の画面の向き(default screen orientation)にロックすることと同等であり、その既定の向きはユーザーエージェントにより既知であるとは限らないためです。したがって、ユーザーエージェントは新しい向きが何になるか、あるいはそもそも変わるかどうかを予測できません。

5.4 共通の安全チェック

共通の安全チェック は、Document に対して次の手順を行います:

  1. もし documentfully active でなければ、"InvalidStateError" の DOMException をスローします。
  2. もし documentsandboxed orientation lock browsing context flag が設定されている場合、"SecurityError" の DOMException をスローします。
  3. もし documentvisibility state が "hidden" であれば、"SecurityError" の DOMException をスローします。

5.5 type 属性

取得時、type 属性はこの this の [[type]] を返します。

5.6 angle 属性

取得時、angle 属性はこの this の [[angle]] を返します。

Note: What does the value given for angle represent?

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 が作成されると、ユーザーエージェント は次を行う MUST です:

  1. screenOrientationcontext関連付けられた ScreenOrientation にします。
  2. screenOrientation[[initialType]] 内部スロットを、画面の 現在の向きの種類 に初期化します。
  3. screenOrientation[[type]] 内部スロットを、画面の 現在の向きの種類 に初期化します。
  4. screenOrientation[[angle]] 内部スロットを、画面の 現在の向きの角度 に初期化します。

8.2 ドキュメントの現在のロックプロミスを拒否する

手順がドキュメント Document の現在のロックプロミスを拒否して null にすることを要求し、かつ DOMString 型の exceptionName で拒否する必要がある場合、ユーザーエージェントMUST 次のことを実行します。

  1. Assert: [[orientationPendingPromise]]null ではないこと。
  2. Let promise be document[[orientationPendingPromise]]
  3. グローバルタスクをキューするDOM 操作タスクソース 上で、 document関連するグローバルオブジェクト を用いて、 promise を新しい exceptionNameDOMException拒否する
  4. document[[orientationPendingPromise]]null に設定する。

8.3 向きのロックを適用する

手順が 向きのロックを適用する ことを要求し、OrientationLockType? 型の orientationDocumentdocument に適用する必要がある場合、ユーザーエージェントMUST 次の手順を実行します。

  1. もし document が並列処理中に fully active(完全にアクティブ)で なくなり、かつ [[orientationPendingPromise]]null でない場合、document の現在のロックプロミスを拒否して null にする を "AbortError" で行う。
  2. topDocumentdocumentトップレベルブラウジングコンテキストアクティブドキュメント とする。
  3. descendantDocs を、もし存在すれば topDocument子孫ナビゲーブルアクティブドキュメント(ツリー順)から構成される 順序付き集合 とする。
  4. docdescendantDocs について順に処理する:
    1. もし docdocument であれば、次へ進む。
    2. もし doc[[orientationPendingPromise]]null であれば、次へ進む。
    3. doc の現在のロックプロミスを拒否して null にする を "AbortError" で行う。
  5. 次のサブステップを 並列に実行する:
    1. もし document完全にアクティブでなくなり、かつ document[[orientationPendingPromise]]null でない場合、document の現在のロックプロミスを拒否して null にする を "AbortError" で行い、 これらの手順を中止する。
    2. もし orientationnull であれば、画面の向きのロックを解除する
    3. それ以外の場合、画面の向きを orientation にロック しようと試みる。プラットフォームの慣習に応じて、ビューポートの描画方法を orientation に合わせて変更する。
    4. もし試行が、既に設定されたユーザーのプリファレンス、プラットフォームの制限、またはその他の理由により失敗した場合:
      1. スクリーンの アクティブな向きのロックnull に設定する。
      2. タスクをキューするDOM 操作タスクソース 上で、 document関連するグローバルオブジェクト を用いて次を行う:
        1. もし document[[orientationPendingPromise]]null でない場合、document の現在のロックプロミスを拒否して null にする を "NotSupportedError" で行う。
        2. これらの手順を中止する。

      これは、ユーザーがウェブアプリケーションによる画面向きの変更を禁止する設定をしている場合や、ユーザーエージェントではなく基盤となるプラットフォーム自体が指定された orientation へのロックを許可していない場合に発生する可能性があります。

    5. スクリーンの アクティブな向きのロックorientation に設定し、現在の向きの種類現在の向きの角度 を、 画面の向きの変更を反映するように更新する。
  6. グローバルタスクをキューするDOM 操作タスクソース 上で、 document関連するグローバルオブジェクト を用いて次を行う:
    1. promisedocument[[orientationPendingPromise]] とする。
    2. document[[orientationPendingPromise]]null に設定する。
    3. 画面の向きの変更手順topDocument に対して実行する。
    4. もし promisenull でない場合、その promise を undefined で解決する。

8.4 画面の向きの変更

ユーザーエージェントが、トップレベルのブラウジングコンテキスト に対して画面の向きが変更されたと判断した場合、またはユーザーがその トップレベルのブラウジングコンテキスト を別の画面に移動した場合、画面の向きの変更手順 をその トップレベルのブラウジングコンテキストアクティブドキュメント に対して実行します。

画面の向きの変更手順 は、Document 型の document に対して次の通り実行されます:

  1. もし document表示状態"hidden" であれば、これらの手順を中止します。
  2. 画面の 現在の向きの種類現在の向きの角度 をそれぞれ typeangle に代入します。
  3. screenOrientationdocument関連するグローバルオブジェクト関連付けられた ScreenOrientation とします。
  4. もし typescreenOrientation[[type]] と等しく、かつ anglescreenOrientation[[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 に対して実行されるたびに、ユーザーエージェントは MUST 次の手順を実行します:

  1. もし documentトップレベルのブラウジングコンテキストアクティブドキュメント でなければ、これらの手順を中止します。
  2. 画面の向きの完全なロック解除手順document に対して実行します。

8.7 向きの完全なロック解除

画面の向きの完全なロック解除手順 は、Document 型の document に対して次の通り実行されます:

  1. もし document[[orientationPendingPromise]]null でない場合、現在のロックプロミスを拒否して null にする を "AbortError" で実行します。
  2. topDocumentdocumentトップレベルブラウジングコンテキストアクティブドキュメント とします。
  3. Apply orientation locknull を指定して topDocument に適用します。

9. フルスクリーン API との相互作用

ユーザーエージェントは SHOULDlock() の使用を、単純なフルスクリーンドキュメントに対する事前条件として制限するべきです。[fullscreen]

document がフルスクリーンを終了するとき、同時に 画面の向きの完全なロック解除手順 も実行されます。[fullscreen]

10. Web アプリケーションマニフェストとの相互作用

Web アプリケーションマニフェスト 仕様は、ウェブアプリケーションが 既定の画面の向き を、orientation メンバーを通じて設定できるようにします。

ユーザーエージェントは SHOULDインストールされたウェブアプリケーション が事前条件として「fullscreen」表示モードで表示されることを要求するべきです(pre-lock conditionとして)。

11. アクセシビリティに関する考慮事項

車椅子のアーム等にデバイスが固定された向きで設置されているユーザーがいる可能性があるため、画面の向きをロックする際にユーザーがデバイスを回転させることを前提とする開発者は、Web コンテンツアクセシビリティ ガイドライン (WCAG) 2.1Orientation 成功基準 を認識しておく必要があります。該当の基準は、コンテンツと機能が 画面の向き にかかわらず利用可能であることを 必須 としています。特定の向きが 重要 である場合、ウェブアプリケーションはユーザーに向きの要件を通知しなければなりません。

12. プライバシーおよびセキュリティに関する考慮事項

画面の typeangle は、フィンガープリンティングの潜在的ベクターになり得ます。以下の緩和策は、デバイスがどのように保持されているかを明らかにしないことでユーザーのプライバシーを保護し、また secondary 向きの種類および関連する角度がフィンガープリンティングに利用されるのを防ぎます。

フィンガープリンティングに抵抗するため(例えばプライベートブラウジング中)、ユーザーエージェントは MAY 次のことを行うことができます:

  1. トップレベルのブラウジングコンテキストのライフタイムの間、画面の natural 向きを [[initialType]] と見なして振る舞う。
  2. type ゲッターの返り値を "portrait-primary" または "landscape-primary" に制限する。どちらを返すかは画面のアスペクト比による。
  3. もし current orientation type[[initialType]] と一致するなら、angle ゲッターに対して 0 を返し、そうでなければ 90 を返す。
  4. 画面の向きが変化した場合、change イベントは、current orientation typeportrait から landscape またはその逆に変わる場合にのみ発火するようにする。

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 に有益なコメントをいただいたことに感謝します。

本 API の初期設計への貢献に対し、Chris Jones および Jonas Sicking に特に感謝します。

D. 参考文献

D.1 規範的参考文献

[appmanifest]
Web アプリケーションマニフェスト。Marcos Caceres; Kenneth Christiansen; Matt Giuca; Aaron Gustafson; Daniel Murphy; Anssi Kostiainen。W3C。2023年5月2日。W3C 作業草案。URL: https://www.w3.org/TR/appmanifest/
[cssom-view]
CSSOM View Module。Simon Pieters。 W3C。2016年3月17日。W3C 作業草案。URL: https://www.w3.org/TR/cssom-view-1/
[dom]
DOM Standard。Anne van Kesteren。WHATWG。 現行標準。URL: https://dom.spec.whatwg.org/
[fullscreen]
Fullscreen API Standard。Philip Jägenstedt。WHATWG。現行標準。URL: https://fullscreen.spec.whatwg.org/
[HTML]
HTML Standard。Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters。WHATWG。現行標準。URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra Standard。Anne van Kesteren; Domenic Denicola。WHATWG。現行標準。URL: https://infra.spec.whatwg.org/
[mediaqueries-5]
Media Queries Level 5。Dean Jackson; Florian Rivoal; Tab Atkins Jr.; Daniel Libby。W3C。2021年12月18日。W3C 作業草案。 URL: https://www.w3.org/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]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words。B. Leiba。IETF。2017年5月。Best Current Practice。URL: https://www.rfc-editor.org/rfc/rfc8174
[WCAG21]
Web Content Accessibility Guidelines (WCAG) 2.1。Andrew Kirkpatrick; Joshue O'Connor; Alastair Campbell; Michael Cooper。W3C。 2018年6月5日。W3C 勧告。URL: https://www.w3.org/TR/WCAG21/
[WEBIDL]
Web IDL Standard。Edgar Chen; Timothy Gu。 WHATWG。現行標準。URL: https://webidl.spec.whatwg.org/