Image for Jednostki viewport – na czym polegają?

Jednostki viewport – na czym polegają?

Czas czytania:

Stylowanie i pozycjonowanie elementów strony www z uwzględnieniem różnych rozdzielczości ekranów może wydawać się skomplikowane. Problemem jest nie tylko wymiarowanie elementów na mobilnych i dużych ekranach, ale i zachowanie proporcjonalności elementów względem siebie np. odstępów i marginesów czy grafik/ikon względem tekstów. Prawidłowo zaprojektowana strona www to taka, która będzie płynnie zmieniała rozmiary elementów wraz ze zmieniającymi się rozdzielczościami ekranów. Dodatkowo powinna uwzględniać granicę, do jakiej element może się zmniejszyć lub zwiększyć.

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">
Znacznik ten pozwala ustawić opcje skalowania strony, w tym także domyślne przybliżenie (zoom). Podana wartość 1 dla initial-scale wyświetla ją bez skalowania. Dla dyrektywy width ustawiona wartość device-width powoduje, że szerokość obszaru wyświetlania jest równa szerokości ekranu urządzenia, a więc witryna jest rozciągnięta w 100%. Aby określić szerokość i wysokość wyświetlanego obszaru strony (np. dla modali), możemy podać dla width i height wartość liczbową w pikselach.

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;
}
lub
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);
}
Aby zapobiec znacznemu powiększeniu tekstu na dużych ekranach, musimy zastosować standardowe Media Queries:
@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;
}
Dzięki temu stopka będzie zawsze na dole strony niezależnie od długości treści.