VisualViewport
Baseline
Widely available
*
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2021年8月.
* 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> |
ブラウザーの互換性
Loading…
関連情報
- Web Viewports Explainer — 視覚的ビューポートとレイアウトビューポートの違いなど、ウェブビューポートの概念に関する有益な説明が記載されています。