Start · Sprachen · JavaScript · Referenz · Window.visualViewport

Window.visualViewport

Eigenschaft

Schreibgeschützte Eigenschaft, die ein <code>VisualViewport</code>-Objekt für den sichtbaren Bereich des Fensters liefert, oder <code>null</code>, wenn das Dokument nicht aktiv ist.

seit JavaScript Baseline: alle modernen Browser (Chrome 61+, Firef Kategorie: webapi

Signatur

window.visualViewport

Beschreibung

window.visualViewport gibt ein VisualViewport-Objekt zurück. Es beschreibt den visuellen Viewport, also den Teil der Seite, den der Nutzer gerade tatsächlich sieht. Anders als der Layout-Viewport (window.innerWidth/innerHeight) wird der visuelle Viewport kleiner, wenn per Pinch gezoomt wird oder die Bildschirmtastatur auf Mobilgeräten einen Teil des Bildschirms verdeckt.

Das Objekt stellt unter anderem width, height, offsetLeft, offsetTop, pageLeft, pageTop und scale bereit. Außerdem löst es die Ereignisse resize und scroll aus (seit Kurzem in Chromium auch scrollend). So lassen sich Elemente trotz Zoom oder eingeblendeter Tastatur korrekt positionieren.

Typische Einsatzfälle:

  • Fixierte Toolbars oberhalb der virtuellen Tastatur anzeigen
  • Chat-Eingabefelder im sichtbaren Bereich halten
  • Tooltips und Overlays beim Pinch-Zoom richtig platzieren
  • Zoomstufe über scale auslesen

Die Eigenschaft ist schreibgeschützt. Sie liefert null, wenn das Dokument nicht vollständig aktiv ist, zum Beispiel bei einem aus dem DOM entfernten <iframe>.

Rückgabewert

Typ
VisualViewport | null
Beschreibung
Das VisualViewport-Objekt des Fensters oder null, wenn das zugehörige Dokument nicht vollständig aktiv ist.

Beispiele

Maße und Zoomfaktor auslesen

const vv = window.visualViewport;

if (vv) {
  console.log(`Sichtbar: ${Math.round(vv.width)} × ${Math.round(vv.height)} px`);
  console.log(`Zoom: ${vv.scale}`);
  console.log(`Versatz zum Layout-Viewport: ${vv.offsetLeft}/${vv.offsetTop}`);
} else {
  console.log('VisualViewport nicht verfügbar');
}
Sichtbar: 390 × 664 px Zoom: 1 Versatz zum Layout-Viewport: 0/0

Toolbar über der Bildschirmtastatur halten

const toolbar = document.querySelector('#toolbar');
const vv = window.visualViewport;

const positionToolbar = () => {
  // Abstand vom unteren Rand des Layout-Viewports zum sichtbaren Bereich
  const bottomGap = window.innerHeight - (vv.height + vv.offsetTop);
  toolbar.style.transform = `translateY(${-Math.max(0, bottomGap)}px)`;
};

if (vv) {
  vv.addEventListener('resize', positionToolbar);
  vv.addEventListener('scroll', positionToolbar);
  positionToolbar();
}

Overlay beim Pinch-Zoom mitskalieren

const badge = document.querySelector('.badge');
const vv = window.visualViewport;

const update = () => {
  // Badge bleibt oben links im sichtbaren Bereich und behält seine Größe
  badge.style.left = `${vv.offsetLeft}px`;
  badge.style.top = `${vv.offsetTop}px`;
  badge.style.transform = `scale(${1 / vv.scale})`;
  badge.style.transformOrigin = '0 0';
};

vv?.addEventListener('resize', update);
vv?.addEventListener('scroll', update);

// Aufräumen, z. B. beim Unmount einer Komponente
const cleanup = () => {
  vv?.removeEventListener('resize', update);
  vv?.removeEventListener('scroll', update);
};

// Wichtig · Fallstricke

  • Auf null prüfen: In abgekoppelten iframes oder inaktiven Dokumenten ist der Wert null. Verwende Optional Chaining (visualViewport?.width).
  • Kompatibilität: Chrome/Edge 61+, Safari 13+ und Firefox 91+ unterstützen die Eigenschaft. In älteren Browsern auf window.innerWidth/innerHeight zurückfallen.
  • Tastatur-Verhalten: iOS Safari verkleinert beim Öffnen der Tastatur nur den visuellen Viewport, nicht den Layout-Viewport. Deshalb bleibt window.innerHeight unverändert, und position: fixed-Elemente können verdeckt werden. Chromium kann dieses Verhalten über das Meta-Attribut interactive-widget ändern.
  • Performance: resize- und scroll-Ereignisse feuern während Gesten sehr häufig. Aktualisierungen deshalb bündeln, etwa mit requestAnimationFrame, und bevorzugt transform statt layoutauslösender Eigenschaften setzen.
  • Werte wie width und height sind Gleitkommazahlen in CSS-Pixeln und enthalten keine Scrollleisten.