Signatur
Beschreibung
Die schreibgeschützte Eigenschaft offsetTop der Schnittstelle VisualViewport gibt an, wie weit die Oberkante des visuellen Viewports (des tatsächlich sichtbaren Bereichs) von der Oberkante des Layout-Viewports entfernt ist. Der Wert wird in CSS-Pixeln angegeben. Ist das Dokument nicht vollständig aktiv, liefert die Eigenschaft 0.
Relevant wird der Wert vor allem auf Mobilgeräten: Zoomt der Nutzer per Pinch-Geste hinein und verschiebt den sichtbaren Ausschnitt, bewegt sich der visuelle Viewport innerhalb des Layout-Viewports. Auch eine eingeblendete Bildschirmtastatur kann den visuellen Viewport verkleinern und verschieben, während der Layout-Viewport gleich bleibt. Elemente mit position: fixed orientieren sich am Layout-Viewport und können dadurch aus dem sichtbaren Bereich rutschen.
Typischer Einsatz: Mit offsetTop (zusammen mit offsetLeft, height und scale) lassen sich schwebende Elemente wie Werkzeugleisten, Hinweis-Banner oder Eingabehilfen so positionieren, dass sie beim Zoomen oder bei eingeblendeter Tastatur sichtbar bleiben. Aktualisiert wird der Wert am besten in den Ereignissen resize und scroll von window.visualViewport.
Nicht verwechseln mit pageTop: pageTop ist der Versatz relativ zum Anfangscontainer (dem Dokument), offsetTop hingegen relativ zum Layout-Viewport. Ohne Zoom ist offsetTop meist 0.
Rückgabewert
0, wenn nicht gezoomt bzw. verschoben wurde oder das Dokument nicht vollständig aktiv ist.Beispiele
Aktuellen Versatz auslesen
const vv = window.visualViewport;
if (vv) {
console.log(`offsetTop: ${vv.offsetTop}px`);
console.log(`pageTop: ${vv.pageTop}px, scale: ${vv.scale}`);
} else {
console.log('VisualViewport API wird nicht unterstützt');
}
Werkzeugleiste beim Pinch-Zoom sichtbar halten
// HTML: <div id="toolbar" style="position: fixed; top: 0; left: 0">…</div>
const toolbar = document.getElementById('toolbar');
const vv = window.visualViewport;
const positionieren = () => {
// Leiste an die Oberkante des sichtbaren Bereichs verschieben
// und den Zoom ausgleichen, damit sie gleich groß bleibt
toolbar.style.transform =
`translate(${vv.offsetLeft}px, ${vv.offsetTop}px) scale(${1 / vv.scale})`;
toolbar.style.transformOrigin = '0 0';
};
vv.addEventListener('resize', positionieren);
vv.addEventListener('scroll', positionieren);
positionieren();
Fußleiste über der Bildschirmtastatur platzieren
const footer = document.querySelector('.chat-eingabe');
const vv = window.visualViewport;
const anTastaturAnpassen = () => {
// Unterkante des sichtbaren Bereichs relativ zum Layout-Viewport
const sichtbareUnterkante = vv.offsetTop + vv.height;
const verdeckt = window.innerHeight - sichtbareUnterkante;
footer.style.bottom = `${Math.max(0, verdeckt)}px`;
};
vv.addEventListener('resize', anTastaturAnpassen);
vv.addEventListener('scroll', anTastaturAnpassen);
// Wichtig · Fallstricke
- Feature-Erkennung:
window.visualViewportkann in älteren Browsernundefinedsein (Firefox erst ab Version 91 standardmäßig). Immer vor dem Zugriff prüfen. - Schreibgeschützt: Zuweisungen werden stillschweigend ignoriert. Zum Verschieben des Ausschnitts gibt es keine direkte API;
window.scrollTo()wirkt auf den Layout-Viewport. - Performance:
scroll- undresize-Ereignisse feuern sehr häufig. Aufwändige DOM-Änderungen mitrequestAnimationFrame()bündeln und bevorzugttransformstatttopverwenden, um Layout-Neuberechnungen zu vermeiden. - Gleitkommawerte: Der Wert ist oft nicht ganzzahlig; bei Vergleichen mit Toleranz arbeiten oder runden.
- Plattformunterschiede: Das Verhalten bei eingeblendeter Bildschirmtastatur unterscheidet sich zwischen iOS Safari und Android Chrome (dort ggf. über
interactive-widgetim Viewport-Meta-Tag steuerbar). Auf Desktop-Browsern bleibt der Wert meist0. - In iframes bezieht sich der Wert auf den Viewport des jeweiligen Frames.