Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

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.

Das VisualViewport-Interface der CSSOM view API repräsentiert das visuelle Viewport für ein bestimmtes Fenster. Für eine Seite, die iframes enthält, wird jedes iframe sowie die enthaltende Seite ein einzigartiges Fensterobjekt haben. Jedes Fenster auf einer Seite wird ein einzigartiges VisualViewport haben, das die Eigenschaften darstellt, die mit diesem Fenster verbunden sind.

Das mobile Web enthält zwei Viewports: den Layout-Viewport und den visuellen Viewport. Der Layout-Viewport erstreckt sich über alle Elemente einer Seite, während der visuelle Viewport das darstellt, was tatsächlich auf dem Bildschirm sichtbar ist. Wenn der Benutzer in die Seite hineinzoomt, verkleinert sich der visuelle Viewport, aber der Layout-Viewport bleibt unverändert. Benutzeroberflächenelemente wie die Bildschirmtastatur (OSK) können den visuellen Viewport verkleinern, ohne den Layout-Viewport zu beeinflussen.

Was passiert, wenn ein Element einer Webseite unabhängig vom sichtbaren Teil einer Webseite auf dem Bildschirm sichtbar sein muss? Zum Beispiel, was ist, wenn Sie ein Set von Bildsteuerungen dauerhaft sichtbar halten müssen, unabhängig vom Zoom-Level des Geräts? Aktuelle Browser variieren, wie sie dies handhaben. Der visuelle Viewport ermöglicht es Webentwicklern, dieses Problem zu lösen, indem Elemente relativ zu dem positioniert werden, was auf dem Bildschirm angezeigt wird.

Sie können den visuellen Viewport eines Fensters mit Window.visualViewport abrufen.

Hinweis: Nur das Top-Level-Fenster hat einen visuellen Viewport, der sich vom Layout-Viewport unterscheidet. Daher ist in der Regel nur das VisualViewport-Objekt des Top-Level-Fensters nützlich. Für ein <iframe> stimmen visuelle Viewport-Metriken wie VisualViewport.width immer mit Layout-Viewport-Metriken wie document.documentElement.clientWidth überein.

EventTarget VisualViewport

Instanz-Eigenschaften

Erbt auch Eigenschaften von seinem Eltern-Interface, EventTarget.

VisualViewport.offsetLeft Schreibgeschützt

Gibt den Versatz der linken Kante des visuellen Viewports von der linken Kante des Layout-Viewports in CSS-Pixeln zurück.

VisualViewport.offsetTop Schreibgeschützt

Gibt den Versatz der oberen Kante des visuellen Viewports von der oberen Kante des Layout-Viewports in CSS-Pixeln zurück.

VisualViewport.pageLeft Schreibgeschützt

Gibt die x-Koordinate des visuellen Viewports relativ zum Ursprung des initialen umgebenden Blocks der oberen Kante in CSS-Pixeln zurück.

VisualViewport.pageTop Schreibgeschützt

Gibt die y-Koordinate des visuellen Viewports relativ zum Ursprung des initialen umgebenden Blocks der oberen Kante in CSS-Pixeln zurück.

VisualViewport.width Schreibgeschützt

Gibt die Breite des visuellen Viewports in CSS-Pixeln zurück.

VisualViewport.height Schreibgeschützt

Gibt die Höhe des visuellen Viewports in CSS-Pixeln zurück.

VisualViewport.scale Schreibgeschützt

Gibt den Pinch-Zoom-Skalierungsfaktor zurück, der auf den visuellen Viewport angewendet wird.

Instanz-Methoden

Erbt auch Methoden von seinem Eltern-Interface, EventTarget.

Ereignisse

Diese Ereignisse können über addEventListener() oder durch Zuweisung eines Ereignislisteners zur entsprechenden oneventname-Eigenschaft dieses Interfaces abgehört werden.

resize

Wird ausgelöst, wenn der visuelle Viewport verändert wird. Auch verfügbar über die onresize-Eigenschaft.

scroll

Wird ausgelöst, wenn der visuelle Viewport gescrollt wird. Auch verfügbar über die onscroll-Eigenschaft.

scrollend

Wird ausgelöst, wenn eine Scroll-Operation auf dem visuellen Viewport endet. Auch verfügbar über die onscrollend-Eigenschaft.

Beispiele

Abrufen von visuellen Viewport-Informationen während des Scrollens und Zoomens

Unser visueller Viewport-Beispiel bietet eine grundlegende Demonstration, wie die verschiedenen Funktionen des visuellen Viewports funktionieren, einschließlich der drei Ereignistypen. Laden Sie die Seite in unterstützenden Desktop- und mobilen Browsern und versuchen Sie, die Seite zu scrollen und zu zoomen. Bei resize und scroll wird die Informationsbox so neu positioniert, dass sie ihre Position relativ zum visuellen Viewport beibehält, und die darin angezeigten Viewport- und Scroll-Informationen werden aktualisiert. Zudem färben wir die Box bei resize und scroll, um anzuzeigen, dass etwas geschieht, und setzen sie bei scrollend zurück.

Sie werden feststellen, dass bei Desktop-Browsern die Werte von Window.scrollX und Window.scrollY aktualisiert werden, wenn das Fenster verschoben wird — die Position des visuellen Viewports ändert sich nicht. Bei mobilen Browsern hingegen werden die Werte von VisualViewport.offsetLeft und VisualViewport.offsetTop in der Regel aktualisiert — meistens verändert sich der visuelle Viewport und nicht die Fensterposition.

Im Beispiel wird die HTML-Informationsbox durch ein <div> mit einer id von output dargestellt, während das CSS der Kürze halber ausgeblendet ist.

html
<p id="instructions">
  Try scrolling around and pinch-zooming to see how the reported values change.
</p>
<div id="output">
  <p id="visual-info"></p>
  <hr />
  <p id="window-info"></p>
</div>

Im JavaScript beginnen wir damit, Referenzen zur Informationsbox zu erhalten, die bei Zoom- und Scroll-Vorgängen aktualisiert wird, sowie zu den beiden Absätzen, die darin enthalten sind. Der erste wird die gemeldeten Werte von VisualViewport.offsetLeft und VisualViewport.offsetTop enthalten, während der zweite die gemeldeten Werte von Window.scrollX und Window.scrollY enthalten wird.

js
const output = document.getElementById("output");
const visualInfo = document.getElementById("visual-info");
const windowInfo = document.getElementById("window-info");

Als Nächstes definieren wir die beiden Schlüssel-Funktionen, die wir ausführen werden, wenn die Ereignisse ausgelöst werden:

  • Die Funktion scrollUpdater() wird bei resize und scroll ausgeführt: Diese Funktion aktualisiert die Position der Informationsbox relativ zum visuellen Viewport, indem die Eigenschaften VisualViewport.offsetTop und VisualViewport.offsetLeft abgefragt und ihre Werte verwendet werden, um die Werte der relevanten Inset-Eigenschaften zu aktualisieren. Außerdem ändern wir die Hintergrundfarbe der Informationsbox, um anzuzeigen, dass etwas geschieht, und führen die Funktion updateText() aus, um die in der Box angezeigten Werte zu aktualisieren.
  • Die Funktion scrollEndUpdater() wird bei scrollend ausgeführt: Diese Funktion stellt die ursprüngliche Farbe der Informationsbox wieder her und führt die Funktion updateText() aus, um sicherzustellen, dass die neuesten Werte bei scrollend angezeigt werden.
js
const scrollUpdater = () => {
  output.style.top = `${visualViewport.offsetTop + 10}px`;
  output.style.left = `${visualViewport.offsetLeft + 10}px`;
  output.style.background = "yellow";
  updateText();
};

const scrollendUpdater = () => {
  output.style.background = "lime";
  updateText();
};

Die Funktion updateText() setzt den HTMLElement.innerText des ersten Absatzes, um die aktuellen Werte von VisualViewport.offsetLeft und VisualViewport.offsetTop anzuzeigen, und den HTMLElement.innerText des zweiten Absatzes, um die aktuellen Werte von Window.scrollX und Window.scrollY anzuzeigen. Nachdem updateText() definiert wurde, wird es sofort aufgerufen, damit die Informationsbox beim Laden der Seite korrekt angezeigt wird.

js
function updateText() {
  visualInfo.innerText = `Visual viewport left: ${visualViewport.offsetLeft.toFixed(2)}
    top: ${visualViewport.offsetTop.toFixed(2)}`;
  windowInfo.innerText = `Window scrollX: ${window.scrollX.toFixed(2)}
    scrollY: ${window.scrollY.toFixed(2)}`;
}

updateText();

Wir haben alle Werte auf zwei Dezimalstellen mit der Methode Number.toFixed() gekürzt, da einige Browser Unterpixel-Werte mit möglicherweise vielen Dezimalstellen rendern.

Jetzt setzen wir Ereignishandler-Eigenschaften sowohl für den visuellen Viewport als auch für das Window-Objekt, um die Schlüssel-Funktionen zur passenden Zeit sowohl auf Mobilgeräten als auch auf dem Desktop auszuführen:

  • Wir setzen die Handler auf window, damit die Position und der Inhalt der Informationsbox bei konventionellen Scroll-Operationen des Fensters aktualisiert werden, beispielsweise beim Scrollen der Seite in einem Desktop-Browser.
  • Wir setzen die Handler auf visualViewport, damit die Position und der Inhalt der Informationsbox bei Scroll- und Zoom-Operationen des visuellen Viewports aktualisiert werden, beispielsweise beim Scrollen und Zoomen der Seite in einem mobilen Browser.
js
visualViewport.onresize = scrollUpdater;
visualViewport.onscroll = scrollUpdater;
visualViewport.onscrollend = scrollendUpdater;
window.onresize = scrollUpdater;
window.onscroll = scrollUpdater;
window.onscrollend = scrollendUpdater;

Die Funktion scrollUpdater() wird bei resize und scroll ausgeführt, während scrollEndUpdater() bei scrollend ausgeführt wird.

Ausblenden einer überlagerten Box beim Zoomen

Dieses Beispiel, entnommen aus der Visual Viewport README, zeigt, wie man ein wenig Code schreibt, der eine überlagerte Box (die beispielsweise eine Werbung enthalten könnte) ausblendet, wenn der Benutzer hineinzoomt. Dies ist eine gute Möglichkeit, die Benutzererfahrung beim Zoomen auf Seiten zu verbessern. Ein Live-Beispiel ist ebenfalls verfügbar.

js
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);

Simulation von position: device-fixed

Dieses Beispiel, ebenfalls entnommen aus der Visual Viewport README, zeigt, wie diese API verwendet werden kann, um position: device-fixed zu simulieren, wodurch Elemente an den visuellen Viewport gebunden werden. Ein Live-Beispiel ist ebenfalls verfügbar.

js
const bottomBar = document.getElementById("bottom-bar");
const viewport = window.visualViewport;
function viewportHandler() {
  const layoutViewport = document.getElementById("layoutViewport");

  // Since the bar is position: fixed we need to offset it by the visual
  // viewport's offset from the layout viewport origin.
  const offsetLeft = viewport.offsetLeft;
  const offsetTop =
    viewport.height -
    layoutViewport.getBoundingClientRect().height +
    viewport.offsetTop;

  // You could also do this by setting style.left and style.top if you
  // use width: 100% instead.
  bottomBar.style.transform = `translate(${offsetLeft}px, ${offsetTop}px) scale(${
    1 / viewport.scale
  })`;
}
window.visualViewport.addEventListener("scroll", viewportHandler);
window.visualViewport.addEventListener("resize", viewportHandler);

Hinweis: Diese Technik sollte mit Vorsicht verwendet werden; die Emulation von position: device-fixed auf diese Weise kann dazu führen, dass das fixierte Element während des Scrollens flackert.

Spezifikationen

Specification
CSSOM View Module
# the-visualviewport-interface

Browser-Kompatibilität

Siehe auch

  • Web Viewports Explainer — nützliche Erklärung der Konzepte von Web-Viewports, einschließlich des Unterschieds zwischen visuellem Viewport und Layout-Viewport.