Viewport-Einheiten waren schon immer umstritten, und das liegt teilweise daran, wie mobile Browser die Dinge komplizierter gemacht haben, indem sie ihre eigenen Vorstellungen über die Implementierung hatten.
Fallbeispiel: Soll die Scrollleiste bei der vw-Einheit berücksichtigt werden? Was ist mit der Navigation oder den Seitensteuerelementen einer Website – sollten diese in die Berechnung einbezogen werden? Dann gibt es noch physische Eigenschaften der Geräte selbst (hallo, Notch!), die nicht übersehen werden können.
Zuerst ein wenig Kontext
Die Spezifikation ist ziemlich vage, wie Viewport-Einheiten berechnet werden sollen. Bei mobilen Geräten konzentrieren wir uns oft auf die vertikale Höhe, also schauen wir uns speziell die Viewporthöhe (vh) an.
vh-Einheit
Entspricht 1 % der Höhe des initialen Containment-Blocks.
Also ja, keine klare Anleitung, wenn es darum geht, geräte- und browserspezifische Unterschiede zu handhaben.
vh wurde ursprünglich vom aktuellen Viewport Ihres Browsers berechnet. Wenn Sie Ihren Browser öffneten und eine Website zu laden begannen, war 1vh gleich 1 % der Bildschirmhöhe abzüglich der Browser-Oberfläche.
Aber! Wenn Sie mit dem Scrollen beginnen, ist es eine andere Geschichte. Sobald Sie an einem Teil der Browser-Oberfläche, wie der Adressleiste, vorbeikommen, würde sich der vh-Wert aktualisieren und das Ergebnis war ein unschöner Sprung im Inhalt.
Safari für iOS war einer der ersten mobilen Browser, der seine Implementierung aktualisierte, indem er einen festen Wert für vh basierend auf der maximalen Bildschirmhöhe definierte. Dadurch würde der Benutzer keine Sprünge auf der Seite erleben, sobald die Adressleiste außer Sicht geriet. Chromes mobiler Browser zog etwa ein Jahr später nach.
Zum Zeitpunkt der Erstellung dieses Artikels gibt es ein Ticket, das dies in Firefox Android beheben soll.
Während die Verwendung eines festen Wertes gut ist, bedeutet dies auch, dass Sie kein volles Element haben können, wenn die Adressleiste sichtbar ist. Der untere Teil Ihres Elements wird abgeschnitten.

CSS Custom Properties: Der Trick zur korrekten Größenbestimmung
Mir kam die Idee, dass CSS Custom Properties und ein paar Zeilen JavaScript der perfekte Weg sein könnten, um die konsistente und korrekte Größenbestimmung zu erreichen, die ich benötigte.
In JavaScript kann man immer den Wert des aktuellen Viewports über die globale Variable window.innerHeight abrufen. Dieser Wert berücksichtigt die Schnittstelle des Browsers und wird aktualisiert, wenn sich seine Sichtbarkeit ändert. Der Trick besteht darin, den Viewport-Wert in einer CSS-Variable zu speichern und diese auf das Element anzuwenden, *anstatt* der vh-Einheit.
Nehmen wir an, unsere CSS Custom Variable ist --vh für dieses Beispiel. Das bedeutet, dass wir sie in unserem CSS wie folgt anwenden wollen:
.my-element {
height: 100vh; /* Fallback for browsers that do not support Custom Properties */
height: calc(var(--vh, 1vh) * 100);
}
Okay, das ist eingerichtet. Holen wir uns jetzt die innere Höhe des Viewports in JavaScript.
// First we get the viewport height and we multiple it by 1% to get a value for a vh unit
let vh = window.innerHeight * 0.01;
// Then we set the value in the --vh custom property to the root of the document
document.documentElement.style.setProperty('--vh', `${vh}px`);
Wir haben JavaScript angewiesen, die Höhe des Viewports zu ermitteln und sie dann durch 1/100 davon zu teilen, um einen Wert zu erhalten, der unserer Viewporthöhen-Einheit zugewiesen werden kann. Dann baten wir JS höflich, die CSS-Variable (--vh) am :root zu erstellen.
Als Ergebnis können wir nun --vh als Höhenwert verwenden, so wie wir es mit jeder anderen vh-Einheit tun würden, sie mit 100 multiplizieren und wir haben die volle gewünschte Höhe.
Es gibt eine weitere Korrektur dafür, die vor kurzem aufgetaucht ist. Matt Smith dokumentiert sie hier. Der Trick ist min-height: -webkit-fill-available; auf dem Body als progressive Verbesserung über 100vh, was auf iOS-Geräten funktionieren sollte.
Moment mal! Noch ein kleines Detail.
Obwohl unsere Arbeit an dieser Stelle erledigt zu sein scheint, haben diejenigen unter Ihnen mit einem geschulten Auge für Details vielleicht bemerkt, dass JavaScript ausgeführt wird, aber die Größe unseres Elements nicht aktualisiert, wenn sich die Höhe des Viewports ändert. Probieren Sie es ruhig aus und ändern Sie die Größe der obigen Demo.
Wir können den Wert von --vh aktualisieren, indem wir auf das resize-Ereignis des Fensters hören. Dies ist nützlich, falls der Benutzer die Ausrichtung des Geräts ändert, z. B. von Querformat zu Hochformat, oder die Navigation beim Scrollen aus dem Sichtfeld gerät.
// We listen to the resize event
window.addEventListener('resize', () => {
// We execute the same script as before
let vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
});
⚠️ Das Aktualisieren des Wertes von --vh löst eine Neuberechnung der Seite aus und der Benutzer kann dadurch einen Sprung erleben. Aus diesem Grund *rate ich nicht dazu, diesen Trick für jedes Projekt zu verwenden oder die gesamte Verwendung der vh-Einheit zu ersetzen*, sondern nur, wenn Sie von Ihren Benutzern einen exakten Viewport-Einheitswert benötigen.
Außerdem möchten Sie vielleicht eine Debounce-Methode für das Resize-Ereignis implementieren, um zu vermeiden, dass zu viele Ereignisse ausgelöst werden, während der Benutzer sein Browserfenster vergrößert. Mehr dazu erfahren Sie in diesem Artikel: Debouncing und Throttling erklärt mit Beispielen
Sie können die obige Demo nun in der Größe ändern und feststellen, dass die CSS-Variable entsprechend aktualisiert wird.
Obwohl ich diese Technik kürzlich in einem Projekt verwendet habe und sie wirklich geholfen hat, sollten Sie immer zweimal nachdenken, bevor Sie das Standardverhalten des Browsers ersetzen. (Zum Beispiel taucht dies häufig bei ::focus auf.) Außerdem tendieren Browser heutzutage dazu, sich sehr schnell zu aktualisieren, also seien Sie sich bewusst, dass eine heutige Lösung morgen vielleicht nicht mehr funktioniert.
In der Zwischenzeit hoffe ich, dass dieser Artikel Ihnen hilft! 👋
Hier ist ein Vorschlag für vhc- und vwc-Einheiten, die in all dem eine Rettung sein könnten.
Sie sollten wirklich eine Art Drosselung verwenden, wenn Sie auf das Resize-Ereignis hören, besonders wenn es eine Neuberechnung auslöst – zum Beispiel wie hier dokumentiert: https://devdocs.io/dom_events/resize
Danke für Ihr Feedback, ich habe eine kleine Notiz zur Debounce-Technik hinzugefügt, aber ich wollte die Demos nicht mit zusätzlichem Code überladen, um sie übersichtlich zu halten ✌️
Habe das noch nicht ausprobiert, aber ich habe monatelang mit diesem Problem gekämpft! Vielen Dank, ich werde es bald versuchen, meine Website zu reparieren.
Könnten Sie Ihren Anwendungsfall näher erläutern? Benötigen Sie ein fließendes Vollbild-Element am oberen Rand der Seite?
Ich habe irgendwo gelesen (ich glaube, auf nngroup.com), dass es am besten ist, ein solches Element etwas kleiner zu machen, damit der Benutzer weiß, dass er nach unten scrollen kann. (Anscheinend gehen einige Benutzer davon aus, dass darunter kein Inhalt mehr ist.)
Das ist genau der Anwendungsfall, für den ich es brauchte. Die erste Ansicht der Website sollte auf Mobilgeräten vollbildtauglich sein, aber wir hatten das Ende abgeschnitten (was das Logo des Kunden war).
Sie könnten diesen Trick auch verwenden, wenn Sie ein Modal haben, das 100vh sein soll, und Sie nicht möchten, dass Ihre Benutzer den unteren Teil aufgrund der Browser-Oberfläche verlieren.
Ich habe vor einem Monat genau mit diesem Problem gekämpft und eine ähnliche Lösung gefunden :D
Ich habe nicht –vh im Root, sondern im Element gemacht, das nur die vh-Einheit benötigte, und mit jQuery, da das Projekt in jQuery war. Aber das Konzept ist dasselbe.
Ähnliche Korrektur mit Modal-Overlay, wenn der Body-Tag Overflow Hidden hat.
in js
function getScrollbarWidth() {
return window.innerWidth – document.documentElement.clientWidth;
}
document.documentElement.style.setProperty(‘–scrollbar-width’,
${getScrollbarWidth()}px);in css
body.modal-opened { padding-right: calc(var(–scrollbar-width)); }
Nur am Rande – wahrscheinlich ist es besser, die Variable –vh100 zu nennen, da sie "100vh" und nicht eine einzelne Einheit ist.
Wenn Sie nur Vollbild-Elemente benötigen, ja, Sie könnten den
calc-Teil überspringen und die Variable auf 100 % von window.innerHeight setzen. Aber wenn Sie ein Element benötigen, das 50vh oder mehr ist, können Sie die Variable verwenden und es so multiplizieren:height: calc(var(--vh, 1vh) * 50);Eine wirklich schöne Lösung.
Es gibt jedoch ein Problem: Wenn die Ausführung eines Skripts fehlschlägt, JS nicht geladen wird oder das Laden lange dauert, wird Ihre Website unbrauchbar.
Fügen Sie eine .js-Klasse zum Body hinzu und lassen Sie die Höhenberechnung nur anwenden, wenn JS geladen wurde – 100vh ist sowohl der Fallback als auch die Nicht-JS/langsames Lade-Version.
Es gibt bereits einen Fallback in CSS, falls JavaScript nicht ausgeführt wird.
In dieser Zeile:
height: calc(var(--vh, 1vh) * 100);gibt esvar(--vh, 1vh), wobei1vhein Fallback ist.Das wird im Artikel nicht wirklich erwähnt, aber CSS Custom Properties können einen Fallback haben, wenn die Eigenschaft nicht definiert ist.
Mehr dazu können Sie hier lesen: https://developer.mozilla.org/en-US/docs/Web/CSS/var
Sie könnten auch einen Standardwert im Root in Ihrem CSS hinzufügen.
Viele Grüße ✌️
Hallo,
Ich benutze den folgenden Code und hatte nie ein Problem damit, dass 100vh nicht die gesamte Höhe einnimmt.
Dies beseitigt das Standardverhalten. Für mich sieht es so aus, als ob das Problem, das Sie haben, dadurch verursacht wird.
Danach füge ich einfach manuell Abstände und Polsterungen hinzu, wie nötig.
Das ist sehr seltsam. Können Sie diese Live-Demo auf Ihrem Handy überprüfen und mir sagen, was Sie sehen?

Hier ist ein Screenshot von Chrome auf dem Handy. Wie Sie sehen können, bezieht sich
100vhauf den Bildschirm ohne die Benutzeroberfläche.Ich habe das auf Chrome auf meinem Mobilgerät zum Laufen gebracht, aber es funktioniert nicht für Safari :(.
Louis, bitte ignoriere meinen ersten Kommentar, nachdem ich das Problem selbst untersucht habe, habe ich mehr entdeckt, als ich gehofft hatte. Ich habe immer angenommen, dass die Viewporthöhe ... Sie wissen schon, die Viewporthöhe ist. Nicht das Chaos, das es tatsächlich ist.
Ich habe also ein bisschen recherchiert... es scheint, dass die einzige einigermaßen zuverlässige Lösung die ist, die Sie in Ihrem Beitrag beschreiben, vielleicht mit einigen Media Queries… Ich untersuche das gerade.
In der Zwischenzeit habe ich eine kleine Demo erstellt, die anscheinend einigermaßen funktioniert… Ich werde versuchen, den Event-Listener für orientationchange zu verwenden, um die Änderung der Ausrichtung zu behandeln und die Höhe von Seiten, die sich unterhalb der ersten 2 Bildschirmhöhen befinden, manuell anzupassen, da die URL-Leiste dann immer ausgeblendet ist.
http://www.patriklegard.com/app
DANKE – dieses Problem hat mich ewig genervt, und es scheint jetzt offensichtlich, aber es ist mir nie in den Sinn gekommen, das Problem auf diese Weise mit innerHeight zu lösen.
Ich würde nicht empfehlen, das resize-Ereignis zu verwenden, da sich die Höhe des Elements beim Scrollen auf Mobilgeräten ändert (besonders auffällig auf Safari iOS). Das bedeutet, wenn auf dem Element ein Hintergrundbild mit der Einstellung "cover" liegt, ändert sich die Hintergrundposition und auch alle absolut positionierten Elemente innerhalb dieses Elements sind betroffen.
Um dieses Problem zu vermeiden, lasse ich das Skript die
vh-Variable nur aktualisieren, wenn die Größenänderung signifikant genug ist (oder in diesem Fall jede Querformat-Ausrichtung, hauptsächlich bei Desktop-Nutzern).Ich stoße auf dieses Problem bei einem Aside mit einem fixierten Footer. Ich möchte, dass der Footer immer sichtbar ist, da er die Schaltflächen "Abbrechen" und "Senden" enthält, aber je nach Scrollen wird er möglicherweise korrekt angezeigt und möglicherweise auch nicht. Haben Sie Vorschläge für einen fixierten Footer in einem Aside auf einem Mobilgerät?
Nur für den Fall, dass jemand anderes auf dieses Problem stößt: Angeblich gibt window.innerHeight in Chrome in der Geräteansicht der Entwicklertools nicht die korrekte Viewporthöhe zurück. Ich habe versucht, diese Methode auf einer meiner persönlichen Websites anzuwenden, war aber ratlos, als ich in die Geräteansicht wechselte, um zu sehen, wie sie auf iOS aussieht, und das Konsolenprotokoll einen anderen Wert für innerHeight als die Viewporthöhe des Geräts anzeigte. Firefox und Safari zeigten korrekte Werte an, Chrome jedoch nicht.
Ich habe diesen Artikel gefunden, der den Grund zu erklären scheint
https://developers.google.com/web/updates/2017/09/visual-viewport-api
Ich musste window.visualViewport.height in der Konsole protokollieren, wenn ich wollte, dass Chrome das visuelle Viewport des Geräts verwendet. Aber wenn Sie tatsächlich auf Ihrem Mobilgerät sind, funktioniert innerHeight einwandfrei, es ist nur, dass innerHeight, wenn Sie ein Mobilgerät auf Ihrem Laptop in den Chrome-Entwicklertools emulieren, nicht wie erwartet funktioniert.
ups, ich meinte window.visualViewport.height
Nur ein kleiner Einwand, aber man könnte genauso gut das
letdurchconstersetzen.