Kurs HTML

4.3. Jednostki relatywne do viewportu (vw, vh, vmin, vmax)

Strona główna > Kurs CSS > Rozdział 4: Jednostki i Kolory w CSS > Jednostki relatywne do viewportu (vw, vh, vmin, vmax)

Wprowadzenie: Wymiary względem okna przeglądarki

Oprócz jednostek relatywnych do rozmiaru czcionki (em, rem) czy wymiarów rodzica (%), CSS oferuje również jednostki, które są bezpośrednio powiązane z rozmiarem **obszaru roboczego okna przeglądarki**, zwanego **viewportem**. Są to jednostki vw, vh, vmin i vmax.

Te jednostki są niezwykle przydatne w tworzeniu elementów, które mają zajmować określoną część ekranu, niezależnie od zagnieżdżenia w strukturze DOM czy rozmiaru czcionki. Są one fundamentem wielu nowoczesnych technik responsywnego projektowania.

Viewport to widoczny obszar strony internetowej w oknie przeglądarki. Jego rozmiar zmienia się, gdy użytkownik zmienia rozmiar okna.

1. vw (Viewport Width)

Jednostka vw reprezentuje **1% szerokości viewportu**.

  • 1vw = 1% szerokości okna przeglądarki.
  • 50vw = 50% szerokości okna przeglądarki.
  • 100vw = 100% szerokości okna przeglądarki.

Rozmiar w vw zmienia się dynamicznie wraz ze zmianą szerokości okna przeglądarki.

.pelna-szerokosc {
  width: 100vw; /* Element zajmie całą szerokość viewportu */
  margin-left: calc(50% - 50vw); /* Ciekawy trik do wyjścia z kontenera */
}

h1 {
  /* Rozmiar czcionki zależny od szerokości viewportu */
  font-size: 5vw; 
}

Uwaga: Używanie vw dla font-size może prowadzić do bardzo małego tekstu na wąskich ekranach i bardzo dużego na szerokich. Często łączy się to z funkcją calc() lub clamp(), aby ograniczyć minimalny i maksymalny rozmiar.

2. vh (Viewport Height)

Jednostka vh reprezentuje **1% wysokości viewportu**.

  • 1vh = 1% wysokości okna przeglądarki.
  • 50vh = 50% wysokości okna przeglądarki.
  • 100vh = 100% wysokości okna przeglądarki.

Rozmiar w vh zmienia się dynamicznie wraz ze zmianą wysokości okna przeglądarki.

.hero-section {
  height: 100vh; /* Sekcja zajmie całą wysokość viewportu */
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-dialog {
  /* Maksymalna wysokość modala to 80% wysokości viewportu */
  max-height: 80vh;
  overflow-y: auto;
}

Problem z 100vh na urządzeniach mobilnych: Na niektórych przeglądarkach mobilnych, 100vh może nie uwzględniać dynamicznie pojawiających się i znikających pasków interfejsu (np. paska adresu). Może to powodować, że element o wysokości 100vh jest częściowo zasłonięty lub pojawia się niechciany scroll. Istnieją nowsze jednostki (svh, lvh, dvh), które próbują rozwiązać ten problem, ale ich wsparcie jest jeszcze ograniczone.

3. vmin (Viewport Minimum)

Jednostka vmin reprezentuje **1% mniejszego wymiaru viewportu** (czyli 1% szerokości lub wysokości, w zależności od tego, która z nich jest aktualnie mniejsza).

  • Jeśli viewport ma wymiary 1200px szerokości i 800px wysokości, to 1vmin = 1% z 800px = 8px.
  • Jeśli viewport ma wymiary 600px szerokości i 900px wysokości, to 1vmin = 1% z 600px = 6px.

vmin jest przydatne, gdy chcemy, aby element zachowywał proporcje lub rozmiar względem mniejszego wymiaru ekranu, np. aby kwadratowy element zawsze mieścił się w całości na ekranie.

.kwadrat-w-viewport {
  width: 80vmin; /* 80% mniejszego wymiaru */
  height: 80vmin; /* 80% mniejszego wymiaru */
  background-color: lightcoral;
}

4. vmax (Viewport Maximum)

Jednostka vmax reprezentuje **1% większego wymiaru viewportu** (czyli 1% szerokości lub wysokości, w zależności od tego, która z nich jest aktualnie większa).

  • Jeśli viewport ma wymiary 1200px szerokości i 800px wysokości, to 1vmax = 1% z 1200px = 12px.
  • Jeśli viewport ma wymiary 600px szerokości i 900px wysokości, to 1vmax = 1% z 900px = 9px.

vmax jest rzadziej używane niż pozostałe jednostki viewportu. Może być przydatne, gdy chcemy, aby rozmiar elementu był powiązany z większym wymiarem ekranu, np. dla bardzo dużych nagłówków na szerokich ekranach.

.duzy-naglowek {
  /* Rozmiar czcionki to 10% większego wymiaru viewportu */
  font-size: 10vmax; 
}

Zastosowania i dobre praktyki

  • Sekcje na całą wysokość/szerokość: 100vh i 100vw są idealne do tworzenia sekcji "hero" lub pełnoekranowych slajdów.
  • Płynna typografia: Używanie vw (często w połączeniu z calc() lub clamp()) do skalowania rozmiaru czcionki wraz ze zmianą szerokości viewportu.
  • Zachowanie proporcji: vmin i vmax mogą pomóc w utrzymaniu proporcji elementów względem rozmiaru ekranu.
  • Ostrożność z font-size: Bezpośrednie użycie vw/vh/vmin/vmax dla font-size może prowadzić do problemów z czytelnością na skrajnych rozmiarach ekranów. Rozważ użycie funkcji clamp(MIN, VAL, MAX), np. font-size: clamp(1rem, 4vw, 3rem);, aby ograniczyć minimalny i maksymalny rozmiar czcionki.
  • Paski przewijania: Pamiętaj, że 100vw obejmuje szerokość paska przewijania (jeśli jest widoczny). Może to powodować pojawienie się poziomego paska przewijania, jeśli element ma width: 100vw; wewnątrz kontenera o ograniczonej szerokości.

Zadania praktyczne

Zadanie 1 (z rozwiązaniem)

Stwórz element <div>, który będzie zajmował dokładnie całą wysokość i całą szerokość dostępnego viewportu, i nadaj mu jasnoniebieskie tło.

Rozwiązanie:

HTML:

<div class="pelny-ekran">Zawartość na pełnym ekranie</div>

CSS:

body {
  margin: 0; /* Usunięcie domyślnych marginesów body */
}

.pelny-ekran {
  width: 100vw; /* 100% szerokości viewportu */
  height: 100vh; /* 100% wysokości viewportu */
  background-color: lightblue;
  display: flex; /* Opcjonalnie, do wyśrodkowania zawartości */
  align-items: center;
  justify-content: center;
  font-size: 2rem;
}

Efekt: Div zajmie cały widoczny obszar okna przeglądarki, niezależnie od jego rozmiaru.

Zadanie 2 (do samodzielnego wykonania)

Ustaw rozmiar czcionki dla elementu <h1> na 8vw. Zmieniaj szerokość okna przeglądarki i obserwuj, jak dynamicznie zmienia się rozmiar nagłówka.

Zadanie 3 (do samodzielnego wykonania)

Stwórz kwadratowy element <div>, którego bok będzie zawsze równy 50% mniejszego wymiaru viewportu (użyj vmin).

FAQ - Najczęściej zadawane pytania

Jaka jest różnica między 100% a 100vw/100vh?

100% odnosi się do wymiaru elementu nadrzędnego (rodzica). 100vw i 100vh odnoszą się zawsze do wymiarów całego viewportu, niezależnie od rodzica. Element o width: 100vw; może być szerszy niż jego rodzic.

Czy jednostki viewportu uwzględniają paski przewijania?

Jednostka vw zazwyczaj uwzględnia szerokość paska przewijania (jeśli jest obecny), co oznacza, że width: 100vw; może spowodować pojawienie się poziomego paska. Jednostka vh zazwyczaj nie uwzględnia wysokości poziomego paska przewijania.

Jak radzić sobie z problemem 100vh na urządzeniach mobilnych?

Jest to złożony problem. Rozwiązania obejmują użycie JavaScript do obliczenia rzeczywistej wysokości widocznego obszaru, stosowanie nowszych jednostek jak dvh (dynamic viewport height - wsparcie rośnie) lub projektowanie layoutu w sposób, który jest mniej zależny od dokładnego 100vh.

Czy mogę używać wartości dziesiętnych z jednostkami viewportu?

Tak, można używać wartości dziesiętnych, np. font-size: 3.5vw; czy height: 80.75vh;.