4.3. Jednostki relatywne do viewportu (vw
, vh
, vmin
, vmax
)
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
i100vw
są idealne do tworzenia sekcji "hero" lub pełnoekranowych slajdów. - Płynna typografia: Używanie
vw
(często w połączeniu zcalc()
lubclamp()
) do skalowania rozmiaru czcionki wraz ze zmianą szerokości viewportu. - Zachowanie proporcji:
vmin
ivmax
mogą pomóc w utrzymaniu proporcji elementów względem rozmiaru ekranu. - Ostrożność z
font-size
: Bezpośrednie użycievw
/vh
/vmin
/vmax
dlafont-size
może prowadzić do problemów z czytelnością na skrajnych rozmiarach ekranów. Rozważ użycie funkcjiclamp(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 mawidth: 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;
.