VisualViewport
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since August 2021.
* Some parts of this feature may have varying levels of support.
VisualViewport
は視覚的ビューポート API のインターフェイスで、指定されたウィンドウの視覚的ビューポートを表します。 iframe があるページでは、コンテナーページだけでなく、それぞれの iframe にも固有のウィンドウオブジェクトが存在します。ページ上の各ウィンドウには、そのウィンドウに関連付けられたプロパティを表す固有の VisualViewport
が存在します。
ウィンドウの視覚的ビューポートは、 Window.visualViewport
を使用して取得することができます。
メモ:
レイアウトビューポートとは異なる視覚的ビューポート持つのは最上位のウィンドウのみです。したがって、一般的には最上位のウィンドウの VisualViewport
オブジェクトのみが使用されます。 <iframe>
の場合、 VisualViewport.width
のような視覚的ビューポートのメトリクスは、常に document.documentElement.clientWidth
などのレイアウトビューポートのメトリクスに対応します。
インスタンスプロパティ
親インターフェイスである EventTarget
から継承したプロパティもあります。
VisualViewport.offsetLeft
読取専用-
視覚的ビューポートの左端のオフセットを、レイアウトビューポートの左端からの CSS ピクセル数で返します。
VisualViewport.offsetTop
読取専用-
視覚的ビューポートの上端のオフセットを、レイアウトビューポートの上端からの CSS ピクセルで返します。
VisualViewport.pageLeft
読取専用-
視覚的ビューポートの x 座標を、初期包含ブロックの上端の原点からの相対 CSS ピクセル数で返します。
VisualViewport.pageTop
読取専用-
視覚的ビューポートの y 座標を、初期包含ブロックの上端の原点からの相対 CSS ピクセル数で返します。
VisualViewport.width
読取専用-
視覚的ビューポートの幅を、 CSS ピクセル単位で返します。
VisualViewport.height
読取専用-
視覚的ビューポートの幅を、 CSS ピクセル単位で返します。
VisualViewport.scale
読取専用-
視覚ビューポートに適用されたピンチズームの倍率を返します。
インスタンスメソッド
親インターフェイスである EventTarget
から継承したメソッドもあります。
イベント
これらのイベントは、 addEventListener()
を使用するか、イベントリスナーをこのインターフェイスの関連する onイベント名
プロパティに代入するかして待ち受けします。
例
ズーム時に重なったボックスを非表示にする
この例では、 Visual Viewport の README から引用し、ユーザーがズームインした際に、オーバーレイされたボックス(例えば広告を含む)を非表示にするコードを少し書く方法を示しています。これは、ページをズームインする際のユーザーの使い勝手を向上させる良い方法です。ライブサンプルも利用できます。
const bottomBar = document.getElementById("bottom-bar");
const viewport = window.visualViewport;
function resizeHandler() {
bottomBar.style.display = viewport.scale > 1.3 ? "none" : "block";
}
window.visualViewport.addEventListener("resize", resizeHandler);
位置のシミュレーション: device-fixed
この例も、 Visual Viewport の README から引用したものですが、この API を使用して position: device-fixed
という、要素を視覚的ビューポートに固定する方法を示しています。ライブサンプルも利用できます。
const bottomBar = document.getElementById("bottom-bar");
const viewport = window.visualViewport;
function viewportHandler() {
const layoutViewport = document.getElementById("layoutViewport");
// バーは position: fixed であるため、レイアウトビューポートの原点から
// 視覚的ビューポートのオフセットを差し引く必要があります。
const offsetLeft = viewport.offsetLeft;
const offsetTop =
viewport.height -
layoutViewport.getBoundingClientRect().height +
viewport.offsetTop;
// これは style.left と style.top を設定することで、
// width: 100% と同じことができます。
bottomBar.style.transform = `translate(${offsetLeft}px, ${offsetTop}px) scale(${
1 / viewport.scale
})`;
}
window.visualViewport.addEventListener("scroll", viewportHandler);
window.visualViewport.addEventListener("resize", viewportHandler);
メモ:
このテクニックは慎重に使用しましょう。このように position: device-fixed
を模倣すると、修正された要素がスクロール時にちらつくことがあります。
仕様書
Specification |
---|
CSSOM View Module # the-visualviewport-interface |
ブラウザーの互換性
BCD tables only load in the browser
関連情報
- Web Viewports Explainer — 視覚的ビューポートとレイアウトビューポートの違いなど、ウェブビューポートの概念に関する有益な説明が記載されています。