Kurs HTML

4.2. Jednostki długości relatywne (%, em, rem)

Strona główna > Kurs CSS > Rozdział 4: Jednostki i Kolory w CSS > Jednostki długości relatywne (%, em, rem)

Wprowadzenie: Elastyczne wymiary

W przeciwieństwie do jednostek absolutnych, **jednostki długości relatywne** definiują rozmiar w odniesieniu do jakiejś innej wartości. Może to być rozmiar czcionki elementu nadrzędnego, rozmiar czcionki elementu głównego (root), rozmiar elementu zawierającego, czy rozmiar okna przeglądarki (viewportu).

Użycie jednostek relatywnych jest kluczowe dla tworzenia **responsywnych** i **dostępnych** stron internetowych, ponieważ pozwalają one elementom i tekstowi skalować się w zależności od kontekstu i preferencji użytkownika.

W tej lekcji skupimy się na trzech podstawowych jednostkach relatywnych: %, em i rem.

1. Procent (%)

Jednostka procentowa (%) definiuje rozmiar jako **procent wartości tej samej właściwości elementu nadrzędnego** (rodzica).

  • Dla właściwości width, % odnosi się do szerokości elementu zawierającego (rodzica).
  • Dla właściwości height, % odnosi się do wysokości elementu zawierającego, **ale tylko jeśli rodzic ma jawnie zdefiniowaną wysokość** (nie auto).
  • Dla właściwości font-size, % odnosi się do rozmiaru czcionki elementu nadrzędnego.
  • Dla właściwości line-height, % odnosi się do rozmiaru czcionki **samego elementu**.
  • Dla margin i padding, % (nawet dla marginesu/paddingu góra/dół) odnosi się do **szerokości** elementu zawierającego.
<div class="rodzic" style="width: 400px; font-size: 16px;">
    <div class="dziecko">Tekst dziecka</div>
</div>
.dziecko {
  width: 50%; /* 50% z 400px = 200px */
  padding: 10%; /* 10% z 400px = 40px (padding lewy/prawy) */
  font-size: 120%; /* 120% z 16px = 19.2px */
}

Zastosowanie: Bardzo często używane do tworzenia płynnych layoutów (np. kolumny o szerokości procentowej), responsywnych obrazków (width: 100%; height: auto;), oraz do skalowania elementów względem ich kontenera.

2. em

Jednostka em jest relatywna do **obliczonego rozmiaru czcionki (font-size) elementu, do którego jest stosowana** (jeśli używana dla font-size) lub **elementu nadrzędnego** (jeśli używana dla innych właściwości, jak margin, padding, width, height).

  • Dla font-size: 1em równa się obliczonemu rozmiarowi czcionki elementu nadrzędnego. Np. jeśli rodzic ma font-size: 16px;, to font-size: 1.2em; dla dziecka oznacza 1.2 * 16px = 19.2px.
  • Dla innych właściwości (margin, padding, width, height, line-height itp.): 1em równa się obliczonemu rozmiarowi czcionki **samego elementu**. Np. jeśli element ma font-size: 20px;, to padding: 1.5em; oznacza padding 1.5 * 20px = 30px.
<div style="font-size: 20px;">
    Rodzic (20px)
    <p style="font-size: 0.8em;"> 
        Dziecko (0.8 * 20px = 16px). Padding tego dziecka ustawiony na 1em będzie wynosił 1 * 16px = 16px.
        <span style="font-size: 1.5em;">
            Wnuk (1.5 * 16px = 24px). Margines tego wnuka ustawiony na 0.5em będzie wynosił 0.5 * 24px = 12px.
        </span>
    </p>
</div>

Problem z em: Efekt kaskadowy. Ponieważ em dla font-size odnosi się do rodzica, zagnieżdżanie elementów ze stylami em może prowadzić do nieoczekiwanych, skumulowanych efektów. Jeśli każdy kolejny poziom zagnieżdżenia ma np. font-size: 0.8em;, tekst będzie stawał się coraz mniejszy.

Zastosowanie: Tradycyjnie używane do tworzenia skalowalnych layoutów i typografii. Szczególnie przydatne, gdy chcemy, aby marginesy, paddingi czy inne wymiary elementu były proporcjonalne do jego własnego rozmiaru czcionki (np. padding: 0.5em 1em;).

3. rem (Root em)

Jednostka rem została wprowadzona, aby rozwiązać problem kaskadowego efektu jednostki em. Jednostka rem jest relatywna **tylko i wyłącznie do rozmiaru czcionki elementu głównego (root) dokumentu**, czyli elementu <html>.

Domyślnie, rozmiar czcionki elementu <html> w większości przeglądarek wynosi 16px. Oznacza to, że:

  • 1rem = rozmiar czcionki elementu <html> (domyślnie 16px)
  • 1.5rem = 1.5 * rozmiar czcionki <html> (domyślnie 24px)
  • 0.8rem = 0.8 * rozmiar czcionki <html> (domyślnie 12.8px)

Niezależnie od tego, jak głęboko zagnieżdżony jest element, 1rem zawsze będzie oznaczać tę samą wartość w pikselach, określoną przez rozmiar czcionki elementu <html>.

html {
  font-size: 16px; /* Domyślnie, ale można zmienić */
}

body {
  font-size: 1rem; /* = 16px */
}

h1 {
  font-size: 2rem; /* = 32px */
  margin-bottom: 1rem; /* = 16px */
}

.sidebar {
  width: 15rem; /* = 240px */
}

.element-zagniezdzony {
  font-size: 0.9rem; /* = 14.4px, niezależnie od font-size rodzica */
  padding: 1rem; /* = 16px */
}

Zalety rem:

  • Przewidywalność: Unika problemu kaskadowego efektu em. Rozmiary są spójne w całym dokumencie.
  • Skalowalność i dostępność: Jeśli użytkownik zmieni domyślny rozmiar czcionki w przeglądarce (co wpływa na font-size elementu <html>), wszystkie elementy zdefiniowane w rem zostaną proporcjonalnie przeskalowane.

Popularna technika (62.5%): Czasami ustawia się html { font-size: 62.5%; }. Ponieważ domyślne 16px * 62.5% = 10px, sprawia to, że 1rem odpowiada 10px, co ułatwia obliczenia (np. 1.6rem = 16px, 2.4rem = 24px). Należy jednak pamiętać, że może to wpłynąć na domyślne rozmiary elementów ustawione przez przeglądarkę.

Zastosowanie: Obecnie rem jest bardzo popularną jednostką, szczególnie do definiowania rozmiarów czcionek, marginesów, paddingów i czasem nawet szerokości/wysokości komponentów, aby zapewnić globalną skalowalność i spójność.

Podsumowanie: Kiedy używać której jednostki?

  • %: Gdy rozmiar ma być zależny od **wymiarów rodzica** (szerokość, wysokość - jeśli zdefiniowana). Idealne dla płynnych layoutów, responsywnych obrazów.
  • em: Gdy rozmiar (np. padding, margin) ma być zależny od **rozmiaru czcionki samego elementu**. Użyteczne do tworzenia komponentów, których wewnętrzne proporcje skalują się wraz z tekstem. Używaj ostrożnie dla font-size ze względu na efekt kaskadowy.
  • rem: Gdy rozmiar ma być zależny od **globalnego rozmiaru czcionki strony** (elementu <html>). Doskonałe dla ogólnej typografii, marginesów, paddingów, zapewniając spójność i globalną skalowalność (dostępność).

Często najlepsze rezultaty osiąga się, **mieszając różne jednostki** w zależności od potrzeb konkretnego elementu i kontekstu.

Zadania praktyczne

Zadanie 1 (z rozwiązaniem)

Stwórz element <div class="kontener"> o szerokości 600px. Wewnątrz niego umieść dwa elementy <div class="kolumna">. Użyj jednostki %, aby każda kolumna zajmowała 48% szerokości kontenera i miała mały margines prawy (np. 2%), tak aby zmieściły się obok siebie (możesz potrzebować float: left; lub Flexbox/Grid do ich ułożenia).

Rozwiązanie (używając float):

HTML:

<div class="kontener">
    <div class="kolumna">Kolumna 1</div>
    <div class="kolumna">Kolumna 2</div>
    <div style="clear: both;"></div> <!-- Clearfix -->
</div>

CSS:

.kontener {
  width: 600px;
  border: 1px solid black; /* Dla wizualizacji */
  overflow: hidden; /* Alternatywa dla clearfix */
}

.kolumna {
  float: left;
  width: 48%; /* 48% z 600px = 288px */
  margin-right: 2%; /* 2% z 600px = 12px */
  background-color: lightgray; /* Dla wizualizacji */
  padding: 10px; /* Dodatkowy padding */
  box-sizing: border-box; /* Ważne, aby padding nie zwiększył szerokości */
}

/* Ostatnia kolumna nie potrzebuje marginesu prawego */
.kolumna:last-child {
  margin-right: 0;
}

Efekt: Dwie kolumny ułożą się obok siebie wewnątrz kontenera, zajmując łącznie 48% + 2% + 48% = 98% jego szerokości.

Zadanie 2 (do samodzielnego wykonania)

Ustaw domyślny font-size dla <html> na 10px (używając techniki 62.5%). Następnie ustaw font-size dla <h1> na 3.2rem i dla <p> na 1.6rem. Jakie będą obliczone rozmiary czcionek w pikselach?

Zadanie 3 (do samodzielnego wykonania)

Stwórz przycisk (<button>) z tekstem. Ustaw jego font-size na 1rem. Następnie użyj jednostki em, aby ustawić jego wewnętrzny padding (padding) tak, aby był proporcjonalny do rozmiaru czcionki (np. 0.5em pionowo i 1em poziomo).

FAQ - Najczęściej zadawane pytania

Która jednostka jest najlepsza: em czy rem?

Obie mają swoje zastosowania. rem jest generalnie bezpieczniejszy i bardziej przewidywalny dla globalnych rozmiarów (czcionki, marginesy, paddingi), ponieważ odnosi się tylko do elementu root, co ułatwia skalowanie całej strony. em jest przydatny, gdy chcesz, aby wymiary elementu (np. padding) były ściśle powiązane z jego własnym rozmiarem czcionki.

Czy % dla line-height działa inaczej?

Tak. W przeciwieństwie do większości innych właściwości, line-height ustawiony w procentach (np. line-height: 150%;) jest obliczany na podstawie rozmiaru czcionki **samego elementu**, a nie rodzica. Jednak często preferuje się używanie wartości bez jednostki dla line-height (np. line-height: 1.5;), ponieważ ta wartość jest dziedziczona jako mnożnik, co daje lepsze rezultaty przy różnych rozmiarach czcionek.

Czy mogę używać rem dla szerokości i wysokości?

Tak, można używać rem do definiowania szerokości, wysokości, marginesów, paddingów itp. Sprawia to, że rozmiar tych elementów będzie skalował się wraz ze zmianą domyślnego rozmiaru czcionki przez użytkownika, co może być pożądane dla zachowania proporcji i dostępności.

Co jeśli rodzic nie ma zdefiniowanej szerokości, a użyję width: 50%; dla dziecka?

Dziecko przyjmie 50% dostępnej szerokości wewnątrz rodzica. Jeśli rodzic jest elementem blokowym, domyślnie zajmuje 100% szerokości swojego kontenera, więc dziecko zajmie 50% szerokości kontenera rodzica. Zasada odniesienia do szerokości rodzica nadal obowiązuje.