Signatur
Beschreibung
Die schreibgeschützte Eigenschaft offsetLeft des VisualViewport-Objekts (erreichbar über window.visualViewport) gibt an, wie weit die linke Kante des visuellen Viewports von der linken Kante des Layout-Viewports entfernt ist. Der Wert wird in CSS-Pixeln angegeben. Ist die Seite nicht gezoomt oder befindet sich der sichtbare Bereich am linken Rand des Layout-Viewports, ist der Wert 0.
Der visuelle Viewport ist der tatsächlich sichtbare Ausschnitt der Seite. Er kann durch Pinch-Zoom oder eine eingeblendete Bildschirmtastatur kleiner sein als der Layout-Viewport. Wenn Nutzer hineinzoomen und den Ausschnitt seitlich verschieben, ändert sich offsetLeft, während window.scrollX gleich bleiben kann. Auf diese Weise lässt sich unterscheiden, ob sich die Seite selbst oder nur der sichtbare Ausschnitt bewegt hat.
Gebraucht wird die Eigenschaft vor allem, um Elemente mit position: fixed (Werkzeugleisten, Tooltips, Menüs, Hinweisbanner) auch bei Pinch-Zoom sichtbar am Rand des tatsächlich sichtbaren Bereichs zu halten. Dazu kombiniert man sie mit offsetTop, width, height und scale und reagiert auf die Ereignisse resize und scroll des VisualViewport. Der Versatz relativ zum Dokument steht dagegen in pageLeft.
Rückgabewert
0, wenn kein Versatz besteht oder das Dokument nicht vollständig aktiv ist.Beispiele
Aktuellen Versatz auslesen
const vv = window.visualViewport;
if (vv) {
console.log(`offsetLeft: ${vv.offsetLeft}px`);
console.log(`pageLeft: ${vv.pageLeft}px`);
console.log(`Zoomfaktor: ${vv.scale}`);
} else {
console.log('VisualViewport wird nicht unterstützt');
}
Fixierte Werkzeugleiste bei Pinch-Zoom mitführen
// HTML: <div id="toolbar" style="position: fixed; left: 0; top: 0">…</div>
const toolbar = document.querySelector('#toolbar');
const vv = window.visualViewport;
const positionToolbar = () => {
// Leiste an die linke obere Ecke des sichtbaren Bereichs setzen
// 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('scroll', positionToolbar);
vv.addEventListener('resize', positionToolbar);
positionToolbar();
Seitliches Verschieben bei Zoom protokollieren (gedrosselt)
const vv = window.visualViewport;
let pending = false;
vv.addEventListener('scroll', () => {
if (pending) return;
pending = true;
requestAnimationFrame(() => {
pending = false;
const sichtbarRechts = vv.offsetLeft + vv.width;
console.log(
`Sichtbar (Layout-Viewport): ${vv.offsetLeft.toFixed(1)}px bis ${sichtbarRechts.toFixed(1)}px`
);
});
});
// Wichtig · Fallstricke
- Nicht mit
HTMLElement.offsetLeftverwechseln: Diese Eigenschaft bezieht sich auf die Position eines Elements relativ zu seinemoffsetParentund hat mit dem Viewport nichts zu tun. offsetLeftundpageLeft:offsetLeftist relativ zum Layout-Viewport,pageLeftrelativ zum Anfang des Dokuments. Für Elemente mitposition: fixedbraucht manoffsetLeft, für absolute Positionen im DokumentpageLeft.- Auf dem Desktop ohne Pinch-Zoom ist der Wert fast immer
0. Das normale Browser-Zoom (Strg/Cmd +) verändert den Layout-Viewport selbst und erzeugt keinen Versatz. - Gibt
0zurück, wenn das Dokument nicht vollständig aktiv ist (z. B. in einem getrennten iframe). - Die Eigenschaft ist schreibgeschützt. Eine Zuweisung wird stillschweigend ignoriert (im Strict Mode wird ein
TypeErrorausgelöst). - Kompatibilität: Vor der Nutzung prüfen, ob
window.visualViewportvorhanden ist. Firefox unterstützt die API auf dem Desktop erst ab Version 91. Ältere Browser liefernundefined. - Leistung:
scroll- undresize-Ereignisse können sehr oft ausgelöst werden. DOM-Änderungen daher am besten überrequestAnimationFramebündeln undtransformstattleft/topverwenden.