Jednostki viewport – na czym polegają?
Czas czytania:
Obszar viewport
Viewport to tzw. obszar renderowania treści w wirtualnym oknie przeglądarki wyświetlanym na ekranie. Mówiąc najprościej, to obszar przeglądarki, w którym widzimy stronę www.
Optymalizacja strony pod urządzenia mobilne to obecnie kluczowy proces dla Front-End Developerów. Podstawą dla uzyskania responsywności jest umieszczenie meta tagu viewport (w sekcji head dokumentu HTML), który daje przeglądarce informacje, w jaki sposób strona ma być wyświetlana na urządzeniach mobilnych.
<meta name="viewport" content="width=device-width, initial-scale=1">
Jednostki CSS
Każdy element renderowany na stronie internetowej możemy zdefiniować pod względem wyglądu i położenia poprzez właściwości opisane w CSS.
Poniżej zostały przedstawione najpopularniejsze jednostki CSS i różnice w sposobie ich obliczania przez przeglądarkę internetową:
- em – jednostka względna, obliczana na podstawie rozmiaru czcionki bezpośredniego rodzica danego elementu;
- rem – jednostka względna, obliczana na podstawie rozmiaru czcionki głównego dokumentu HTML (najwyższego elementu w DOM strony), taką właściwość najczęściej ustawiamy za pomocą:
:root {
font-size: 10px;
}
html {
font-size: 10px;
}
- % – jednostka względna, obliczana w procentach w zależności od rozmiaru elementu rodzica;
- px – jednostka bezwzględna, dla urządzeń o niskich dpi 1px odpowiada jednemu pikselowi, dla drukarek i wysokiej rozdzielczości ekranów urządzeń 1px zawiera w sobie wiele pikseli. Jednostka ta jest absolutna, tzn. nie jest relatywna względem innych jednostek.
Wymienione jednostki mogą okazać się niewystarczające, aby strona była poprawnie wyświetlania na urządzeniach o różnych rozdzielczościach. W tym celu zwykle stosuje się osobne definicje stylów w Media Queries. Inną metodą jest zastosowanie do tego specjalnych jednostek viewport, które zapewniają dostosowywanie się wymiarów elementów do okna przeglądarki internetowej.
Jednostki viewport CSS
Aby uzyskać dynamicznie zmieniające się rozmiary elementów na stronie względem okna przeglądarki, należy ustawić im rozmiar za pomocą jednostek tzw. Viewport Units, które reprezentują procent aktualnych wymiarów obszaru roboczego ekranu:
- vw – (viewport width) procentowa szerokość – względem szerokości okna przeglądarki;
- vh – (viewport height) procentowa wysokość – względem wysokości okna przeglądarki;
- vmin – (viewport minimum) mniejsza z wartości vw lub vh;
- vmax – (viewport maximum) większa z wartości vw lub vh.
Viewport width i viewport height
To jednostki relatywne względem rozmiaru okna przeglądarki. Element o szerokości 1vw będzie zajmował 1% szerokości aktualnego obszaru roboczego ekranu, a 1vh będzie równy 1% wysokości.
Przykład
- width: 50vw – element o wysokości połowy wysokości aktualnego okna przeglądarki
- height: 50vh – element o wysokości połowy wysokości aktualnego okna przeglądarki
- 1024px x 768px – aktualny rozmiar okna przeglądarki internetowej
- 1024px × 0.01 × 50 = 512px – obliczona wartość szerokości elementu
- 768px × 0.01 × 50 = 384px – obliczona wartość wysokości elementu
Viewport minimum i viewport maximum
Jednostki te są podobne do vw i vh, jednak ich wartość jest obliczana z aktualnie mniejszej lub większej wartości tj. wysokości lub szerokości okna przeglądarki.
Vmin w przypadku gdy wysokość okna przeglądarki jest mniejsza niż jej szerokość, obliczona zostanie na podstawie jej wysokości. Natomiast vmax dla tego samego przypadku odwoła się do większej z dwóch wartości czyli do szerokości.
Przykład
- width: 50vmin – element o szerokości połowy z aktualnie większej wartości – wysokości lub szerokości
- height: 50vmax – element o wysokości połowy z aktualnie mniejszej wartości – wysokości lub szerokości
- 1024px x 768px – aktualny rozmiar okna przeglądarki internetowej
- 768px × 0.01 × 50 = 384px – obliczona wartość vmin dla szerokości elementu
- 1024px × 0.01 × 50 = 512px – obliczona wartość vmax dla wysokości elementu
Dla ekranu pionowego element przyjmie wysokość połowy krótszego boku okna przeglądarki czyli szerokości. Jeśli zmienimy orientację ekranu na poziomą, wartość dopasuje się do krótszej krawędzi okna i w tym przypadku będzie nią już wysokość.
Przykłady użycia i rozwiązania błędów
Jednostki viewports można stosować nie tylko dla width czy height, ale także dla określania wszystkich elementów, którym można ustawić rozmiar, tak jak w przypadku rozmiaru tekstu, grafiki czy marginesów i odstępów.
Full screen
Jednostkę vh często stosuje się do uzyskania tzw. efektu full screen – sekcji pełnoekranowej, która zajmuje całą wysokość ekranu. Korzystając z tego rozwiązania, może jednak okazać się, że w widoku horyzontalnym (landscape) może nie być wystarczająco dużo miejsca na treść. Dlatego należy zastosować pewne ograniczenia, które pozwolą uniknąć wychodzenia zawartości poza kontener. W tym celu należy określić np. minimalną wysokość sekcji potrzebną do zmieszczenia całej przewidzianej w niej treści.
min-height: 400px;
Problem z zastosowaniem wartości 100vw
Jeśli ustawimy szerokość elementu na 100vw, to przeglądarka, wyliczając jego rozmiar, doda do niej szerokość pionowego scrolla, co spowoduje rozszerzenie zawartości strony. Aby zapobiec takiej sytuacji w przypadku dyrektywy width, lepiej zastosować ogranicznik, ustawiając maksymalną szerokość elementu na 100%.
max-width: 100%;
Rozmiar tekstu
Jednostki viewport są bardzo przydatne w responsywnej typografii. Przy zmianie rozmiarów obszaru roboczego rozmiar tekstu dopasowuje się wg odpowiednio wyliczanej wartości. Takie rozwiązanie niesie jednak ryzyko, że przy ekranach mobilnych tekst może okazać się tak mały, że będzie nieczytelny lub na większych ekranach nieproporcjonalnie duży w stosunku do innych elementów na stronie.
Wg standardów projektowania stron minimalny rozmiar czcionki na urządzeniu mobilnym nie powinien przekraczać 14 pikseli. Trzeba więc nadać tekstowi minimalną wielkość czcionki.
Funkcja CSS calc()
Funkcja calc() przy zastosowaniu jednostek viewport i stałych jednostek zapobiega niekontrolowanemu zmniejszaniu rozmiarów elementu. Dzięki niej możemy ustanowić podstawową wartość tekstu na 14px i dodać do niej 2 jednostki vw.
.main-text {
font-size: calc(14px + 2vw);
}
@media (min-width: 1600px) {
.main-text {
font-size: 40px;
}
}
Łączenie różnych jednostek z wykorzystaniem calc()
Funkcja calc() pozwala na określenie rozmiarów jako działania matematycznego łączącego różne jednostki. Możemy używać nawet jednostek względnych CSS (em lub rem) zamiast px. Zapewnia to większą kontrolę nad zmianą rozmiaru elementu.
width: calc(100% - 80px);
width: calc(10vh + 2rem);
font-size: calc(1rem + .3vw);
Przerwy między elementami
Jednostki viewport sprawdzą się także dla ustawiania marginesów i odstępów np. od nagłówka strony czy w siatce elementów.
CSS Grid
Jeśli przy użyciu CSS Grid odstępy między elementami (artykułami, sekcjami, boxami) będą zależne od szerokości lub wysokości okna przeglądarki, to cały layout strony będzie bardziej dynamiczny. Dla grid-gap zastosowanie jednostek viewport wraz z funkcją calc() gwarantuje przerwy między elementami w siatce.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-gap: calc(16px + 1vh) calc(16px + 0.5vw);
}
Modale
Dla wyświetlania modali ważne jest, aby bez względu na rozmiar obszaru roboczego zawsze ustawiały się na górze strony. Zastosowanie jednostek viewport w tym przypadku pozwoli dodać dynamiczny odstęp od góry strony, który będzie się zmieniał w oparciu o wysokość okna przeglądarki.
.modal-container {
top: 10vh;
}
Sticky footer
Jednym z częściej pojawiających się problemów przy tworzeniu responsywnej zawartości stron jest ustawienie stopki zawsze na dole ekranu. Jeśli treść witryny jest krótka i nie wypełnia całej wysokości okna, stopka pozycjonuje się zaraz pod treścią i nie przylega do dołu strony. Aby rozwiązać ten problem, musimy nadać głównej treści wysokość równą wysokości obszaru viewport, odejmując od niego wysokość nagłówka i stopki. Taki efekt można uzyskać na kilka sposobów. Najlepszym z nich jest zastosowanie jednostki viewport wraz z flexbox. Wystarczy nadać elementowi body dokumentu wysokość równą 100vh, i zmusić główny kontener zawartości strony, aby zajął pozostałe wolne miejsce.
body {
min-height: 100vh;
display: flex
flex-direction: column;
}
main-container {
/* To wymusi na głównym kontenerze dynamiczne zajęcie całego wolnego miejsca*/
flex-grow: 1;
}