Signatur
Beschreibung
Die schreibgeschützte Eigenschaft scale der Schnittstelle VisualViewport liefert den Skalierungsfaktor, den der Nutzer per Pinch-Zoom (Zwei-Finger-Geste auf Touch-Geräten oder Trackpad-Zoom) auf den visuellen Viewport angewendet hat. Ein Wert von 1 heißt: nicht gezoomt. Werte über 1 bedeuten hineingezoomt, Werte unter 1 herausgezoomt (soweit das Viewport-Meta-Tag das zulässt).
Der Browser-Zoom per Tastatur (Strg++) wird nicht erfasst. Dieser Zoom ändert das Layout und damit window.devicePixelRatio. scale meldet ausschließlich den Pinch-Zoom, der den Layout-Viewport unverändert lässt.
Typische Anwendungsfälle:
- Fixierte Elemente wie Toolbars oder Tooltips beim Zoomen in konstanter Bildschirmgröße halten, indem man sie mit
1 / scalegegenskaliert. - Analysieren, ob Nutzer häufig zoomen müssen (ein Hinweis auf zu kleine Schrift).
- Eigene Zoom-Oberflächen, zum Beispiel für Karten oder Bildbetrachter.
Den Wert fragt man am besten im Handler des Events resize von window.visualViewport ab. Dieses Event wird auch bei Pinch-Zoom ausgelöst.
Rückgabewert
1, 1.5, 2.75). Gibt 0 zurück, wenn das zugehörige Dokument nicht vollständig aktiv ist (z. B. ein abgelöstes iframe).Beispiele
Aktuellen Zoom-Faktor auslesen
const vv = window.visualViewport;
if (vv) {
console.log(`Pinch-Zoom: ${vv.scale.toFixed(2)}x`);
console.log(vv.scale > 1 ? 'Seite ist hineingezoomt' : 'Kein Zoom aktiv');
} else {
console.log('VisualViewport-API nicht verfügbar');
}
Toolbar trotz Pinch-Zoom in konstanter Größe halten
const toolbar = document.querySelector('#toolbar');
const vv = window.visualViewport;
const updateToolbar = () => {
// Gegenskalierung: Toolbar bleibt optisch gleich groß
toolbar.style.transformOrigin = '0 0';
toolbar.style.transform =
`translate(${vv.offsetLeft}px, ${vv.offsetTop}px) scale(${1 / vv.scale})`;
};
vv.addEventListener('resize', updateToolbar);
vv.addEventListener('scroll', updateToolbar);
updateToolbar();
Zoom-Verhalten für Analyse protokollieren (entprellt)
let timer;
let maxScale = 1;
window.visualViewport?.addEventListener('resize', (event) => {
const { scale } = event.target;
maxScale = Math.max(maxScale, scale);
clearTimeout(timer);
timer = setTimeout(() => {
console.log(`Zoom beendet bei ${scale.toFixed(2)}x, Maximum bisher: ${maxScale.toFixed(2)}x`);
}, 300);
});
// Wichtig · Fallstricke
- Nur Pinch-Zoom: Der Browser-Zoom per Tastatur oder Menü verändert
scalenicht. Diesen Zoom kann man näherungsweise überwindow.devicePixelRatioerkennen. - Wert
0: Ist das Dokument nicht vollständig aktiv (z. B. ein aus dem DOM entferntes iframe), liefert die Eigenschaft0. Vor einer Division wie1 / scalediesen Fall abfangen. - Desktop-Browser: Ohne Touch oder Trackpad-Geste bleibt der Wert meist dauerhaft bei
1. - Viewport-Meta-Tag: Mit
user-scalable=noodermaximum-scale=1kann der Zoom eingeschränkt sein. Aus Gründen der Barrierefreiheit sollte man den Zoom aber nicht sperren. iOS-Safari ignoriert diese Sperre inzwischen. - Performance:
resize- undscroll-Events feuern während der Geste sehr häufig. Aufwendige DOM-Updates daher mitrequestAnimationFramebündeln oder entprellen. - Kompatibilität: Chrome 61+, Safari 13+ und Firefox 91+ unterstützen die API. Vor der Nutzung sollte man per
window.visualViewportprüfen, ob sie verfügbar ist.