まとめ
仕様から改めて以下を確認しました。
アクティブなタブに直接表示されているトップレベルのDocumentであれば、仕様上visualViewportはnullにはならない(= fully active なので)
HTML仕様から以下のような解釈をしたのでそれを整理します。
「ブラウザのタブに直接表示されているトップレベルのWindow上でvisualViewportはnullにならない」
背景
ページの可視領域を算出する為にvisualViewportを使用しました。
ブラウザでも値が取得できていたのですが、TypeScriptで書いていると、型推論でVisualViewport | nullとなっていました。

The visualViewport read-only property of the Window interface returns a VisualViewport object representing the visual viewport for a given window, or null if current document is not fully active.
window.visualViewportはdocumentがfully activeでない場合にnullを返す可能性がある。
https://developer.mozilla.org/en-US/docs/Web/API/Window/visualViewport
ブラウザのタブに直接表示されているトップレベルのWindow上では、nullにならないということを理解する為に仕様を調査しました。
documentがfully activeとは
HTML Standard では、次のような Document を fully active と定義しています。
A Document d is said to be fully active when d is the active document of a
navigable navigable, and either navigable is a top-level traversable or
navigable's container document is fully active.
https://html.spec.whatwg.org/multipage/document-sequences.html#fully-active-documents
これを日本語で言い換えると、dをdocumentとすると、次の条件を満たすdがfully activeです
- dがnavigableのアクティブなdocumentである
- navigableが最上位のtraversableである、またはnavigableのコンテナ文書がfully active
navigableとはそのdocumentを表示していて、履歴も持っているコンテナ(枠)のことです。
A navigable presents a Document to the user via its active session history entry.
例
- ブラウザタブの中の「表示枠」
- iframe のような「入れ子の表示枠」
top-level traversableとはブラウザウィンドウやブラウザタブのことです。
A top-level traversable is a traversable navigable with a null parent.
top-level traversable とは、親の navigable を持たない(parent が null な) traversable な navigable のことです。
A user agent holds a top-level traversable set (a set of top-level traversables). These are typically presented to the user in the form of browser windows or browser tabs.
ユーザーエージェントは、最上位のtraversable集合(最上位のtraversableの集合)を保持する。これらは通常、ブラウザウィンドウやブラウザタブの形でユーザーに提示される。
https://html.spec.whatwg.org/multipage/document-sequences.html#top-level-traversables
よって、現在タブに表示されているトップレベルのDocumentは仕様上fully activeとみなせます。
タブ直下(トップレベル)のページであることを確認する方法
window.topは、ウィンドウオブジェクトの階層における最上位のウィンドウを返します
https://developer.mozilla.org/ja/docs/Web/API/Window/top
親ページ(タブ直下)側で実行するコード
//タブ直下のwindowの場合はtrue
window === window.top
//iframeの場合はfalse (iframe は最上位ではない)
window.frames[0].contentWindow === window.top
結論
今回のようなケース(アクティブなタブに直接表示されているトップレベルの Document)では、仕様上そのDocumentはfully activeなので、対応ブラウザであればvisualViewportはnullにはなりません。
最後に
HTML仕様について読みましたがとても難しかったです
認識違っていればコメントお願いします🙇
参考
- https://developer.mozilla.org/en-US/docs/Web/API/Window/visualViewport
- https://stackoverflow.com/questions/67689503/what-is-top-level-navigation-in-browser-terminology-and-in-what-ways-it-can-be-t
- https://html.spec.whatwg.org/multipage/document-sequences.html#fully-active-documents
- https://developer.mozilla.org/ja/docs/Web/API/Window/top
- https://html.spec.whatwg.org/multipage/document-sequences.html#top-level-traversables
- https://html.spec.whatwg.org/multipage/document-sequences.html#navigables