t28.dev

Viewport って具体的になに?

2025/12/1に公開
Tech

viewport っていうと…

  • <meta name="viewport" content="width=device-width, initial-scale=1"> とか
  • 100vh とか

じゃん?となるが…まー曖昧。そもそも viewport って何だ?って考えると困ったので調べた。

Viewport

ビューポートとは、連続メディアの初期包含ブロックを確立するために使用するユーザーエージェント機能です。

ref: MDN - ビューポートとは何か

…よく分からないので、単語の意味を仕様から調べる。

連続メディア はスクロールすれば全部が見られる表示環境1のことで、例えばスマホやPCの画面のこと。

Media that match ‘none’ or ‘scroll’ are said to be continuous media, while those that match paged are said to be paged media

ref: Media Queries Level 5 - § 4.5. Block-Axis Overflow: the overflow-block feature

初期包含ブロック<html> のレイアウトの基準となる矩形のこと。

initial containing block

The containing block of the root element. The initial containing block establishes a block formatting context. See CSS2.1§10.1 for continuous media; and [CSS-PAGE-3] for paged media for its position and dimensions.

ref: CSS Display Module Level 3 - § Appendix A: Glossary

以上のことから頑張って言い換えると、viewport とは「スクロールできる環境でページのレイアウトの基準として使われる、ブラウザが提供する矩形領域」のこと。 まだ難しい。身も蓋もないが、MDN に書いてある 文書の表示領域そのもの で一旦納得しておく。

ウェブブラウザーの文脈では、これは通常、 UI やメニューバーなどを除いたブラウザーウィンドウと同一です。つまり、あなたが見ている文書の表示領域そのものです。

ref: MDN - ビューポートとは何か

Initial viewport と Actual viewport

document を読み込んだ後、viewport は 2つの段階を踏む2:

  • Initial viewport
  • Actual viewport

Initial viewport

Initial viewport はユーザーエージェントのウィンドウまたは表示領域によって指定された viewport を指し、 さらに以下の要素で上書きされる前のものである:

  • ユーザーエージェントのスタイル
  • HTML タグ 3
  • 作成者のスタイル

initial viewport

This refers to the viewport before any UA or author styles have overridden the viewport given by the window or viewing area of the UA. Note that the initial viewport size will change with the size of the window or viewing area.

ref: CSS Viewport Module Level 1 - 2. §The viewport

ユーザーエージェントのスタイルによる上書きが具体的に何を指すかは MDN・仕様に (多分) 書いていない。 おそらく、ブラウザが勝手に(?)に設定する viewport の幅のことだと思う。 Viewport の幅は PC ブラウザとモバイルブラウザで扱いが異なる。 PC ブラウザではウィンドウの幅がそのまま viewport の幅になる。 一方モバイルブラウザは画面よりも幅の広い仮想 viewport 4 でレンダリングして、その結果を画面に収まるように縮小して表示する。

Some mobile devices and other narrow screens render pages in a virtual window or viewport that is wider than the screen, and then shrink the rendered result down to fit the screen size.

ref: MDN - Viewport width and screen width

作成者のスタイルによる上書きも同様に書かれていない。おそらく、CSS で viewport の設定をする @viewport rule のことを指している。 しかし @viewport仕様から削除されたので、これは考えなくて良さそう。

Actual viewport

Actual viewport は <meta> タグを処理した後の viewport を指す。

This is the viewport you get after processing the viewport tag.

ref: CSS Viewport Module Level 1 - 2. §The viewport

今どきのウェブアプリは <meta name="viewport" content="width=device-width, initial-scale=1.0" /> がデフォルトのようなので:

<meta> タグの処理をして width をデバイス幅に設定された viewport が actual viewport って考えて良さそう。

Layout viewport と Visual viewport

MDN では viewport を「現在見えている矩形の領域」としているが、 その後の記述仕様は viewport を 2 つに分類している 5:

  • Layout viewport
  • Visual viewport

これらの定義的な記述は CSSOM View ModuleCSS Viewport Module Level 1 を見る限り👇️のみで、 「visual viewport のスクロール領域は layout viewport という別の viewport である」ことだけが説明されている 6

The visual viewport is a kind of viewport whose scrolling area is another viewport, called the layout viewport.

ref: CSSOM View Module - §2. Terminology

Layout viewport

Actual viewport を layout viewport として扱う issue があるので、layout viewport は「<meta> タグを処理した後の viewport」と理解できる。

ISSUE3 Make actual viewport the layout viewport, define visual viewport.

ref: CSS Viewport Module Level 1 - ISSUE3

困ったことにこれ以上の説明をMDN・仕様から見つけられない。 検索結果や AI は「コンテンツをレイアウトする際の基準となる表示領域」のような説明をするが、 おそらくこれは 「layout viewport の内部座標系は pinch-zoom の影響を受けない」ことを元に 勝手に考えたものだと思う。仕様にはそれに準ずる記述がない。

Visual viewport

Visual viewport は layout viewport の現在表示されている部分。

visual viewport is the currently visible portion of the layout viewport.

ref: MDN - Viewport concepts

pinch-zoom(visual viewport の scale transform) で拡大縮小することで、 visual viewport の width/height/offset を変えることが出来る。つまり layout viewport 内のどの部分が見えるかを変えられる。

こんな感じ
+----------------------------------+
|         Layout Viewport          |
|   +--------------------------+   |
|   |     Visual Viewport      |   |
|   |        (zoom-in)         |   |
|   +--------------------------+   |
+----------------------------------+

また仮想キーボードが出ると visual viewport は縮む(height が小さくなる)

The user is viewing a document in a mobile user agent. The document focuses an offscreen text input element, showing a virtual keyboard which shrinks the visual viewport.

ref: CSSOM View Module - EXAMPLE3

Zoom で影響を与える viewport

ズームは 2 種類ある:

There are two kinds of zoom, page zoom which affects the size of the initial viewport, and the visual viewport scale factor which acts like a magnifying glass and does not affect the initial viewport or actual viewport. [CSS-DEVICE-ADAPT]

ref: CSSOM View Module - 2.2. Zooming

page zoom は initial viewport のサイズを変える。 一方 pinch-zoom は initial viewport と actual viewport には影響を与えず、visual viewport のサイズを変える。

下の画像は左から

  • 通常。
  • pinch-zoom 結果。initial viewport/actual viewport に影響を与えていないので、拡大した分だけ右側が見切れている。
  • page zoom 結果。initial viewport のサイズを変えているので、見切れるのではなく overflow した分が省略されたり改行されたりしている。

まとめ

感覚的優先でまとめると:

Viewport の種類まとめ
Initial viewport何も処理をしていない最初の viewport。PC ブラウザではウィンドウ幅、モバイルブラウザでは仮想 viewport 幅 (980px ぐらい)。
Actual viewport / Layout viewport<meta> タグを処理した後の viewport。width=device-width を設定すればモバイルブラウザもウィンドウ幅 8 になる。
Visual viewportpinch-zoom や仮想キーボードに影響を受ける、実際に見えている領域

JavaScript から viewport を見る

innerWidthinnerHeight は viewport (具体的にはlayout viewport) の大きさを取得するプロパティである。

The innerWidth attribute must return the viewport width including the size of a rendered scroll bar (if any), or zero if there is no viewport.

partial interface Window {
    // ...
    // viewport
    [Replaceable] readonly attribute long innerWidth;
    [Replaceable] readonly attribute long innerHeight;
    // ...
};

ref: CSSOM View Module - 4. Extensions to the Window Interface

仕様にはこの viewport がどの viewport を指しているか書かれていないが、MDN 曰く、innerWidthinnerHeight は layout viewport の大きさを表している。

The area within the innerHeight and innerWidth is generally considered the layout viewport.

ref: MDN - Viewport sizes are mutable

Visual viewport のサイズは VisualViewport API から取得することが出来る:

  • Layout viewport を基準に visualViewport がどこにあるか (offsetLeft / offsetTop)
  • document を基準に visualViewport がどこにあるか (pageLeft / pageTop)
  • Visual viewport の大きさ ( width / height / scale )
interface VisualViewport : EventTarget {
  readonly attribute double offsetLeft;
  readonly attribute double offsetTop;

  readonly attribute double pageLeft;
  readonly attribute double pageTop;

  readonly attribute double width;
  readonly attribute double height;

  readonly attribute double scale;
  // ...
};

CSS の単位から viewport を見る

Viewport-percentage の長さは 初期包含ブロック のサイズを基準にしていて、初期包含ブロック 自体は viewport のサイズに基づいている9

The viewport-percentage lengths are relative to the size of the initial containing block—which is itself based on the size of either the viewport (for continuous media) or the page area (for paged media). When the height or width of the initial containing block is changed, they are scaled accordingly.

ref: CSS Values and Units Module Level 4 - 6.1.2. Viewport-percentage Lengths: the *vw, *vh, *vi, *vb, *vmin, *vmax units

動的に展開・縮小される ユーザーエージェントインターフェースにおいて、viewport のサイズを 3 に分類している:

  • 縮小されることを想定したサイズ -> large viewport
  • 展開されることを想定したサイズ -> small viewport
  • 動的に考慮されたサイズ -> dynamic viewport

これらに対応して、viewport-percentage の長さの単位は 4種類ある:

  • large viewport-percentage units (lv*)
  • default viewport-percentage units (v*)
  • small viewport-percentage units (sv*)
  • dynamic viewport-percentage units (dv*)

There are four variants of the viewport-percentage length units, corresponding to three (possibly identical) notions of the viewport size.

ref: CSS Values and Units Module Level 4 - 6.1.2.1. The Large, Small, and Dynamic Viewport Sizes

他の単位より古くからある v* の default は 18 December 2023 時点の仕様では large viewport を指している。 一方、27 October 2023時点の仕様では UA-default viewport を指しているUA-default viewport というのはつまり、ブラウザ(実装)側でお好きにってこと (多分)。そりゃ vh 問題とか言われる訳だ…。

Footnotes

  1. A media type is a broad category of user-agent devices on which a document may be displayed. (§ 2.3. Media Types) を読んで勝手に言い換えた。

  2. Initial viewport と Actual viewport をまとめて呼ぶ名前がない。

  3. MDN には書かれているが、仕様書には書かれていない項目

  4. 約980px (Chrome for Developers - 仮想ビューポートとは)

  5. Visual viewport と Layout viewport をまとめて呼ぶ名前がない。

  6. これだけで分かる人、いるの?

  7. CSSOM View Module が “pinch-zoom” はハイフンあり、“page zoom” はハイフンなしで表記している。

  8. 設定値は “デバイス” だけど…

  9. 「Viewport-percentage は viewport のサイズを基準にしている」ってほぼ説明になっていない気がする。