Uwaga! Trwają prace nad nową wersją serwisu. Mogą występować przejściowe problemy z jego funkcjonowaniem. Przepraszam za niedogodności!
⛔ Potrzebujesz wsparcia? Oceny CV? A może Code Review? ✅ Dołącz do naszej społeczności na Discordzie!
Każdy programista znający CSS spotkał się z jednostką vh. Jednak mało który zdaje sobie sprawę, jakie konsekwencje może mieć jej nieprzemyślane użycie – szczególnie jeśli mówimy o aplikacjach mobilnych. Zobaczmy, jakie problemy mogą wystąpić podczas korzystania z vh oraz jak im zaradzić!
Chcesz lepiej zapamiętać to zagadnienie? Wykonaj warsztat z HTML i CSS: Responsywność, aby osiągnąć swój cel!
Czy słyszałeś o uciętym buttonie, który kosztował ponad 8 milionów dolarów? Ta historia pokazuje, jak istotne jest poprawne pozycjonowanie elementów na urządzeniach mobilnych. Pozostań po bezpiecznej stronie i naucz się nowych jednostek dla określania wysokości viewportu!
Korzystając z przeglądarek internetowych, często wchodzimy na strony, które zajmują 100% dostępnej przestrzeni w pionie. Jako przykład może posłużyć nam strona logowania Facebooka czy Twittera. Aby osiągnąć taki efekt, możemy skorzystać z szeroko wykorzystywanej reguły CSS:
.app-container { width: 100%; height: 100vh; overflow: hidden; }
Okazuje się jednak, że taki sposób definiowania wysokości kontenerów powoduje spore utrudnienia podczas korzystania z aplikacji webowych na telefonach.
W 2015 roku Apple w swoich przeglądarkach Safari wprowadza dynamiczny pasek URL. Chowa się on i wysuwa podczas scrollowania strony. Jest to funkcja, która często pozostaje niezauważona, ale znacząco zwiększa nam dostępną przestrzeń na ekranie. Obecnie chyba każdy producent przeglądarek internetowych zaadoptował to rozwiązanie.
Spójrz na poniższy GIF, aby zobaczyć przykład działania dynamicznego paska.
Niestety tuż po wprowadzeniu tej funkcjonalności użytkownicy zaczęli zgłaszać błędy związane z tym, że layouty stron skaczą, a niektóre przyciski na dole stron internetowych są zasłonięte. Jak to możliwe?
Różnica między vh na komputerze i telefonie jest subtelna, ale może powodować sporo problemów.
Na urządzeniach mobilnych obszar viewportu zaczyna się od górnej krawędzi paska, ale jest przesunięty w dół o jego wysokość. Na komputerze viewport zaczyna się od paska i nie ma żadnego przesunięcia.
Spróbujmy wspólnie odtworzyć błąd, który może wynikać z wyżej opisanej różnicy.
Stworzę prostą aplikację – formularz subskrypcji usługi. Chciałbym, aby użytkownik miał możliwość skorzystania z darmowego okresu próbnego po kliknięciu przycisku na samym dole ekranu. Korzystając z zasad UX, taki przycisk umieszczam niżej, by miał trochę mniejszą wagę wizualną niż przycisk służący do wyboru płatnej subskrypcji.
Chciałbym, aby przycisk darmowej subskrypcji był „przyklejony” do dołu ekranu. Tworzę wspomnianą wcześniej regułę height: 100vh
. Dodatkowo dodaję overflow: hidden
, gdyż aplikacja nie ma się scrollować. Korzystam z flexboxa, aby elementy zajmowały całą dostępną przestrzeń.
.app-container { height: 100vh; overflow: hidden; }
Aplikację podejrzysz dzięki GitHub Pages, a jej kod znajdziesz na repozytorium. Poniżej załączam zrzuty ekranu, które z niej pochodzą.
W przeglądarce komputerowej nie zobaczymy żadnego problemu, dlatego skorzystałem z przeglądarki Blisk, która emuluje różne telefony. Podgląd z testów umieszczam na zdjęciu poniżej.
Tutaj też wszystko prezentuje się dobrze. Stronę mogę wrzucić na produkcję i cieszyć się wolnym popołudniem.
Dla pewności sprawdzam projekt na swoim smartfonie i… ku mojemu zdziwieniu strona wcale nie wygląda tak, jak powinna – jest ucięta o wysokość paska URL. Wypchnął on zawartość strony w dół, nie respektując ustawionej wcześniej wartości 100vh.
Zrzut ekranu ze smartfona Huawei P20
Zrzut ekranu ze smartfona iPhone 8
Zobaczmy kolejny przykład. Tym razem to prawdziwa gra webowa, gdzie również użyto wysokości 100vh do stworzenia kontenera:
Źródło: real-app z https://nicolas-hoizey.com/articles/2015/02/18/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers/
Jak widzisz, obecność dynamicznego paska URL przesuwa zawartość strony.
Pomoc nadchodzi dopiero po 7 latach od wprowadzenia dynamicznych belek URL.
Grupa robocza CSS tworzy trzy nowe jednostki, a na początku 2022 roku Apple wprowadza je do Safari. Nowe jednostki biorą pod uwagę zachowanie dynamicznych elementów interfejsu przeglądarki (w tym paska URL) i pozwalają w bezpieczny sposób tworzyć layouty rozciągające się na całą dostępną przestrzeń ekranu.
Grupa robocza CSS wyróżnia trzy nowe jednostki:
W momencie pisania tego artykułu jednostki są dostępne w trzech największych przeglądarkach desktopowych i mobilnych (Chrome, Firefox i Safari), dlatego polecam testowanie ich w tych aplikacjach.
Żródło: https://caniuse.com/viewport-unit-variants
Poznajmy wspólnie każdą z trzech nowych jednostek!
Large viewport height (w skrócie lvh) to wysokość widoku obliczona przy założeniu, że elementy interfejsu przeglądarki są schowane.
Aby lepiej zrozumieć definicję, spójrz na poniższą grafikę ilustrującą lvh.
Aby skorzystać z jednostki lvh, użyję poniższej reguły CSS. Teraz, gdy wszystkie „pływające” elementy przeglądarki (np. pasek wyszukiwarki, pasek nawigacji) będą schowane, element o klasie .app-container powinien zajmować całą dostępną przestrzeń pionową:
.app-container { height: 100lvh; }
Jednostki lvh stosujemy dla kontenerów, które:
Jeśli by się nad tym zastanowić, to można dojść do wniosku, że 100lvh jest po prostu równe obecnemu 100vh.
Small viewport height (w skrócie svh) oznacza wysokość dostępnego obszaru ekranu obliczoną przy założeniu, że elementy interfejsu przeglądarki są wysunięte.
Poniższa grafika pomoże Ci w zrozumieniu definicji svh.
Reguła CSS może w tym przypadku wyglądać tak:
.app-container { height: 100svh; }
Jednostki svh stosujemy dla kontenerów, które:
Ostatnią i najbardziej użyteczną jednostką jest dynamiczna wysokość viewportu (dvh).
Oznacza ona wysokość dostępnego obszaru ekranu, która jest obliczana w zależności od stanu interfejsu przeglądarki:
Aby użyć dynamicznej wysokości viewportu, skorzystałbym z tej reguły:
.app-container { height: 100dvh; }
Jednostka dvh wydaje się być najlepszym wyborem. Mamy pewność, że:
Może teraz zastanawiasz się: po co stosować lvh i svh, skoro dvh łączy najlepsze cechy obu?
Stosowanie dvh zmieni wysokość elementów podczas scrollowania – gdy wyświetlimy stronę i elementy interfejsu przeglądarki będą widoczne, wysokość kontenera będzie mniejsza. Gdy zaczniemy scrollować i elementy interfejsu się schowają, wysokość kontenera będzie większa. Kontener musi więc być ostylowany tak, by zmiany jego wysokości nie wpływały rażąco na wygląd.
Weźmy pod uwagę przykładowy kod:
.text.text-big { font-size: 2dvh; }
Jak myślisz, co stanie się podczas scrollowania strony, gdy wielkość czcionki jest uzależniona od dynamicznej jednostki? Jeśli pomyślałeś, że nagle zmieni się jej wielkość, to miałeś rację!
Podobny problem napotkamy w innych przypadkach, kiedy zależy nam na stałym rozmiarze elementów. Mogą to być na przykład okna iframe, wykresy czy grafiki, które muszą zachować stałe proporcje.
Działanie nowych jednostek możesz przetestować w tej aplikacji, a kod podejrzysz na repozytorium. Jeśli Twoja przeglądarka nie wspiera nowych jednostek, to nie będziesz miał możliwości ich ustawienia.
Poznane jednostki pomogą Ci uniknąć popularnych błędów związanych z wysokością kontenerów w aplikacjach webowych. Ciesz się nimi w Twoim kolejnym projekcie i bądź pewien, że layout nie zachowa się w sposób nieprzewidziany. Pamiętaj, by sprawdzić, czy przeglądarka, dla której tworzysz aplikacje, wspiera nowe rozwiązanie.
Udostępnij ten artykuł:
Potrzebujesz cotygodniowej dawki motywacji?
Zapisz się i zgarnij za darmo e-book o wartości 39 zł!
PS. Zazwyczaj rozsyłam 1-2 wiadomości na tydzień. Nikomu nie będę udostępniał Twojego adresu email.
Mam coś dla Ciebie!
W każdy piątek rozsyłam motywujący do nauki programowania newsletter!
Dodatkowo od razu otrzymasz ode mnie e-book o wartości 39 zł. To ponad 40 stron konkretów o nauce programowania i pracy w IT.
PS Zazwyczaj wysyłam 1-2 wiadomości na tydzień. Nikomu nie będę udostępniał Twojego adresu e-mail.