Zmienność viewportów na iOS/Android

Zmienność viewportów na iOS/Android

Responsywność na urządzeniach mobilnych to nie tylko szerokość – to również dynamiczna zmienność wysokości widocznego obszaru. Systemy iOS i Android posiadają elementy interfejsu (np. pasek adresu, przyciski systemowe), które pojawiają się i znikają – co wpływa na to, jak przeglądarka interpretuje wysokość viewportu.

Co powoduje zmiany viewportu?

W mobilnych przeglądarkach (szczególnie Safari i Chrome):

  • Na początku widoczny jest pasek adresu i dolne przyciski systemowe
  • Po rozpoczęciu przewijania – paski mogą się schować
  • Viewport ulega zmianie – ale 100vh w CSS nadal oznacza pełną wysokość ekranu, nie widocznego obszaru

Efekt? Komponenty o wysokości 100vh mogą wystawać poza ekran, powodować przewijanie lub nagłe „skoki” w layoucie.

Jak zachowuje się vh w praktyce?
  • Na desktopie: 100vh = dokładnie wysokość okna przeglądarki
  • Na Androidzie/iOS: 100vh = wysokość całego ekranu, nawet jeśli część zasłania interfejs

Oznacza to, że 100vh nie bierze pod uwagę tego, co naprawdę widać. Może to powodować np.:

  • ukrycie przycisku CTA poza widocznym obszarem,
  • konieczność przewijania nawet w sekcjach typu hero,
  • nieprzyjemne „skoki” układu przy przewijaniu w górę i w dół.
Jakie jednostki rozwiązują problem?

Nowoczesne przeglądarki mobilne wspierają trzy nowe jednostki wysokości:

  • svhSmall Viewport Height: minimalny viewport z paskami
  • lvhLarge Viewport Height: maksymalny viewport po ukryciu pasków
  • dvhDynamic Viewport Height: aktualny stan widocznego viewportu
Przykład problemu i jego rozwiązania

Problem z `100vh`:

.hero {
  height: 100vh;
}

Na iOS nagłówek może być wyższy niż widoczny ekran – część się obcina lub użytkownik musi przewijać.

Poprawione rozwiązanie:

.hero {
  height: 100vh;   /* fallback */
  height: 100dvh;  /* dynamiczna wysokość widocznego ekranu */
}

Dzięki temu komponent zajmuje dokładnie tyle miejsca, ile rzeczywiście jest dostępne – niezależnie od stanu pasków systemowych.

Wspierane przeglądarki

Nowe jednostki dvh, svh, lvh są obecnie wspierane przez:

  • Chrome (od v108)
  • Safari (od iOS 15.4)
  • Firefox (od v110)
  • Edge (Chromium)

Starsze wersje ich nie rozumieją, ale dzięki nadpisywaniu wartości CSS – można pisać bezpieczne fallbacki.

Testowanie na urządzeniach mobilnych

Aby naprawdę sprawdzić zachowanie layoutu, warto:

  • użyć fizycznego urządzenia (iPhone, Android),
  • przetestować przewijanie i pojawianie się pasków,
  • skorzystać z Chrome DevTools w trybie urządzenia mobilnego, ale ostrożnie – nie oddaje w 100% zachowania viewportu,
  • obserwować zmianę window.innerHeight w konsoli przeglądarki.
Ćwiczenie

Stwórz sekcję .fullscreen-message, która zawiera:

  • nagłówek, opis i przycisk,
  • layout pionowo wyśrodkowany,
  • tło, które zajmuje dokładnie widoczny ekran mobilny,
  • działa poprawnie przy przewijaniu na iOS/Android.

Użyj kombinacji 100vh (jako fallback) i 100dvh. Przetestuj na telefonie lub w DevTools.

Wniosek

Urządzenia mobilne to środowiska dynamiczne – paski systemowe, gesty, scrollowanie wpływają na layout. Klasyczne jednostki jak vh nie dają pełnej kontroli. Nowoczesne jednostki viewportu rozwiązują realny problem UX, pozwalając budować interfejsy przewidywalne i dostosowane do kontekstu użytkownika – niezależnie od systemu i modelu telefonu.