Wenn 100vh lügt: Mobile Viewport-Probleme beheben
Sie erstellen einen Hero-Bereich mit voller Höhe. Er sieht in den Chrome DevTools perfekt aus. Sie öffnen ihn auf Ihrem Smartphone und der untere Inhalt wird abgeschnitten — der CTA-Button, dessen Positionierung Sie sorgfältig vorgenommen haben, versteckt sich hinter der Adressleiste des Browsers. Kommt Ihnen das bekannt vor?
Das ist keine Safari-spezifische Eigenart mehr. Es ist eine Konsequenz daraus, wie Viewport-Einheiten grundlegend definiert sind, und es betrifft auch Chrome, Firefox und Samsung Internet auf Mobilgeräten.
Wichtigste Erkenntnisse
100vhwird auf Mobilgeräten gegen den großen Viewport (eingezogene Symbolleisten) berechnet, der höher ist als das, was Benutzer beim initialen Laden tatsächlich sehen.- Verwenden Sie
100svhfür stabile Layouts mit voller Höhe, die auf den sichtbaren Bildschirm passen, wenn Symbolleisten angezeigt werden. - Reservieren Sie
100dvhfür Fälle, in denen Sie explizit möchten, dass sich das Layout mit Änderungen der Browser-UI anpasst, und akzeptieren Sie die damit verbundenen Reflow-Kosten. - Kombinieren Sie Viewport-Einheiten mit
env(safe-area-inset-bottom)auf randlosen Displays, um zu verhindern, dass Inhalte hinter der System-UI landen.
Warum 100vh auf Mobilgeräten lügt
Die Grundursache liegt in zwei unterschiedlichen Viewport-Konzepten:
- Layout-Viewport: Was der Browser zur Berechnung von CSS-Längen verwendet, einschließlich
vh - Visueller Viewport: Was der Benutzer tatsächlich auf dem Bildschirm sieht
Mobile Browser halten den Layout-Viewport absichtlich konstant, auch wenn sich die Adressleiste und die Navigations-Symbolleiste beim Scrollen einziehen. Das bedeutet, 100vh wird gegen den erweiterten Symbolleisten-Zustand berechnet — den großen Viewport — und dieser Wert ist größer als der sichtbare Bildschirm beim ersten Laden der Seite.
Das ist kein Bug. Die CSS-Spezifikation definiert
vhals äquivalent zulvh(Large Viewport Height). Der Browser verhält sich korrekt. Ihr Layout berücksichtigt es nur nicht.
Deshalb sieht die mobile Emulation in DevTools gut aus: Sie simuliert keine dynamische Browser-UI. Die Adressleiste zieht sich in einem Simulator nie ein.
Die Auswirkungen in der Praxis
- Hero-Bereiche laufen beim initialen Laden um 56–80px über
- Fixierte Footer werden von der Navigationsleiste verdeckt
- Vollbild-Modale schneiden Inhalte unten ab
- Layouts springen, wenn sich Symbolleisten während des Scrollens einziehen (wenn Sie
dvhverwenden)
Discover how at OpenReplay.com.
Moderne Lösungen: svh, dvh und lvh
CSS bietet Ihnen jetzt drei explizite Viewport-Höhen-Einheiten, die verschiedenen Symbolleisten-Zuständen entsprechen:
| Einheit | Repräsentiert | Am besten für |
|---|---|---|
lvh | Großer Viewport (Symbolleisten eingezogen) | Gleich wie aktuelles vh-Verhalten |
svh | Kleiner Viewport (Symbolleisten sichtbar) | Stabile Layouts, immer sichtbare Inhalte |
dvh | Dynamischer Viewport (aktueller Zustand) | Anpassende Layouts, verursacht aber Reflow |
Für die meisten Bereiche mit voller Höhe: Verwenden Sie svh
.hero {
height: 100vh; /* Fallback für ältere Browser */
height: 100svh; /* Passt in den sichtbaren Bildschirm beim Laden */
}
100svh dimensioniert das Element auf den kleinsten möglichen Viewport — das heißt, es passt auch dann, wenn Symbolleisten vollständig sichtbar sind. Kein Überlauf, kein Abschneiden.
Wenn Sie dynamische Anpassung wünschen: Verwenden Sie dvh mit Vorsicht
.full-height {
height: 100vh; /* Fallback */
height: 100dvh; /* Passt Größe an, wenn sich Symbolleisten einziehen */
}
Warnung: dvh berechnet sich neu, wenn sich die Browser-UI während des Scrollens ändert. Dies kann sichtbare Layout-Shifts und Repaints verursachen. Es ist nicht die richtige Standardeinstellung für die meisten Hero-Bereiche oder Modale — verwenden Sie es nur, wenn Sie explizit möchten, dass sich das Element mit dem Symbolleisten-Zustand anpasst.
Browser-Unterstützung
svh, dvh und lvh werden in Chrome 108+, Safari 15.4+ und Firefox 101+ unterstützt. Zusammen deckt das über 90% der Nutzer weltweit ab. Für ältere Browser übernimmt der 100vh-Fallback den Rest.
Erwähnenswerte Sonderfälle
Safe-Area-Insets: Auf randlosen Displays (iPhone Notch/Dynamic Island) kombinieren Sie Viewport-Einheiten mit env(safe-area-inset-bottom), um zu vermeiden, dass Inhalte hinter der System-UI landen:
.hero {
height: 100svh;
padding-bottom: env(safe-area-inset-bottom);
}
Bildschirmtastatur: Die virtuelle Tastatur beeinflusst hauptsächlich den visuellen Viewport, und ihre Interaktion mit der Layout-Viewport-Dimensionierung kann zwischen Browsern und WebViews variieren. Dies ist getrennt von symbolleisten-gesteuerten Viewport-Einheiten und erfordert möglicherweise JavaScript-Handling oder die VirtualKeyboard API als Progressive Enhancement.
WebViews und eingebettete Browser: In-App-Browser (Instagram, LinkedIn) haben oft nicht standardmäßiges Viewport-Verhalten. Testen Sie auf echten Geräten, nicht nur in System-Browsern.
Fazit
Hören Sie auf, 100vh als Standardeinstellung für mobile Layouts mit voller Höhe zu verwenden. Nutzen Sie 100svh für stabile Bereiche, die beim Laden in den sichtbaren Bildschirm passen müssen. Reservieren Sie 100dvh für Fälle, in denen dynamische Größenanpassung beabsichtigt ist. Die neue Viewport-Einheiten-Familie existiert genau deshalb, weil das alte Verhalten immer ein Kompromiss war — jetzt haben Sie die Werkzeuge, um explizit zu sein, was Sie tatsächlich wollen.
FAQs
Nicht überall. 100svh gibt Ihnen die kleinste Viewport-Höhe, die kürzer ist als 100vh. Für Elemente, die den Bildschirm erst nach dem Einziehen der Symbolleisten füllen sollen, sind 100lvh oder 100dvh möglicherweise geeigneter. Verwenden Sie 100svh speziell für Inhalte, die beim initialen Laden der Seite mit angezeigten Symbolleisten vollständig sichtbar sein müssen.
Das kann sein. Da dvh sich jedes Mal neu berechnet, wenn sich die Browser-Symbolleiste während des Scrollens einzieht oder erweitert, löst es Layout-Neuberechnungen und Repaints aus. Für statische Hero-Bereiche oder Modale ist dieser Overhead unnötig. Reservieren Sie dvh für Elemente, bei denen Sie absichtlich möchten, dass die Höhe dem aktuell sichtbaren Viewport in Echtzeit folgt.
Das Verhalten variiert. In Standard-iframes beziehen sich Viewport-Einheiten auf den eigenen Viewport des iframes, nicht auf die übergeordnete Seite. In WebViews, die von In-App-Browsern wie Instagram oder Facebook verwendet werden, ist das Symbolleisten-Verhalten nicht standardisiert und Viewport-Einheiten-Berechnungen können unvorhersehbar sein. Testen Sie immer auf echten Geräten in den spezifischen eingebetteten Kontexten, denen Ihre Nutzer begegnen.
Die Einheiten svh, dvh und lvh werden nicht von der virtuellen Tastatur beeinflusst. Die Tastatur verkleinert den visuellen Viewport, aber nicht den Layout-Viewport, auf den sich diese Einheiten beziehen. Um tastaturbedingte Layout-Shifts zu handhaben, schauen Sie sich die VirtualKeyboard API an, die Ihnen programmatische Kontrolle darüber gibt, wie Ihr Layout auf Änderungen der Tastatursichtbarkeit reagiert.
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..