Różnica między jednostkami em i rem w CSS

Arkadiusz Meszka    15 października 2019 | Ostatnia modyfikacja: 18 maja 2020

Kaskadowe arkusze stylów (CSS – Cascade Style Sheets) kilkanaście lat temu całkowicie odmieniły oblicze tworzenia stron www. Nadal są jednak pewne niuanse, które początkującym, a także bardziej zaawansowanym użytkownikom sprawiają problemy. W tym artykule postaram się w prosty sposób objaśnić różnicę między jednostkami miary rem i em.

Jednostka em

Em (relative to the font-size of the element) to jednostka miary, która bazuje na rozmiarze czcionki danego elementu lub bezpośredniego rodzica tego elementu.

Załóżmy, że mamy blok div o klasie container, dla którego mamy ustawioną czcionkę 20px:

div.container {
    font-size: 20px;
}

W ramach tego bloku umieścimy nagłówek H2.

<div class="container">
    <h2>Lorem ipsum dolor</h2>
</div>

Jeśli rozmiar tego nagłówka zdefiniujemy na 1 em, czyli:

div.container h2 {
    font-size: 1em;
}

Wtedy ten nagłówek H2 będzie mieć właśnie rozmiar 20px, ponieważ dziedziczy go po swoim rodzicu, czyli bloku div o klasie container.

Jednostkę em możemy też stosować do definiowania rozmiarów elementów. Jeśli w ramach bloku div.container zrobimy kolejny blok div i nadamy temu blokowi szerokość 3 em, będzie mieć on 60 px szerokości (1em to 20px, 20px * 3 = 60px):

<div class="container">
    <div class="child_inside_container"></div>
</div>

.container {
    font-size: 20px;
}

.child_inside_container {
    width: 3em;
}

Powyższy kod sprawi właśnie to, co opisałem powyżej, czyli .child_inside_container będzie mieć 60 px szerokości.

Jednostka rem

Rem (relative to font-size of the root element) działa niemal na identycznej zasadzie, jak em, z tą różnicą, że rozmiar nie jest dziedziczony bezpośrednio od rodzica, tylko z najwyższego elementu w DOM strony. Najczęściej jest to znacznik HTML.

Więc jeśli nadamy elementowi HTML rozmiar czcionki 20 px:

html {
    font-size: 20px;
}

To później w ramach całego drzewa strony jednostka 1 rem oznacza 20 px. Więc jeśli dowolnemu nagłówkowi, akapitowi czy innemu elementowi nadamy font size 1 rem, będzie to 20px:

h2, p, span {
    font-size: 1rem;
}

Wszystkie elementy h2, p oraz span będą mieć rozmiar czcionki 20px.

Jeśli jakiemuś elementowi nadamy szerokość 10 rem i wysokość 5 rem:

article {
    width: 10rem;
    height: 5rem;
}

Element ten będzie mieć 200 px szerokości i 100 px wysokości, ponieważ 20 x 10 = 200 i 20 x 5 = 100.

Dlaczego stosowanie rem jest bardzo wygodne i praktyczne?

Stosowanie jednostki rem jest bardzo praktyczne w responsywnych projektach. Dlaczego? Nie musimy zmieniać rozmiaru czcionek wszystkich elementów na stronie, wystarczy, że zmienimy rozmiar czcionki najwyższego elementu w hierarchii, czyli html.

Możemy np. ustawić, aby na najwyższych rozdzielczościach czcionka html miała 22px:

html {
    font-size: 22px;
}

A pozostałe elementy rozmiary relatywne, czyli np.:

h2 {
    font-size: 2.5rem;
}

p, li {
    font-size: 1rem;
}

I wraz z malejącą rozdzielczością zmieniać rozmiar tej czcionki na mniejszy, aby wielkość czcionki czy szerokość lub wysokość poszczególnych elementów dopasowywała się do malejącej rozdzielczości:

@media all and (max-width: 1600px) {
    html {
        font-size: 20px;
    }
}

@media all and (max-width: 1400px) {
    html {
        font-size: 18px;
    }
}

@media all and (max-width: 1200px) {
    html {
        font-size: 18px;
    }
}

W powyższych responsywnych komendach nie musimy od nowa definiować wielkości h2, p czy li, ponieważ automatycznie rozmiar czcionki tych elementów będzie mniejszy, gdyż zmniejszył się rozmiar czcionki elementu HTML, od którego dziedziczą one wielkość czcionki.

Jest to szczególnie przydatne, gdy nie mamy stałego rozmiaru containera z treścią na stronie, lecz rozmiar określony w procentach. Jeśli korzystamy z Twitter Bootstrap lub podobnego frameworka i dla komputerów ustalamy stałą szerokość containera, jednostka rem staje się przydatna w ostylowaniu na urządzenia mobilne.

Podsumowanie

Mam nadzieję, że w przystępny sposób udało mi się przybliżyć Ci, na czym polega stosowanie jednostek em i rem. Jeśli zrozumiałeś, na czym to polega, prawdopodobnie już nigdy nie będziesz definiować wielkości czcionek w pikselach 🙂

Miłego kodowania.

Udostępnij wpis
1 Gwiazdka2 Gwiazdki3 Gwiazdki4 Gwiazdki5 Gwiazdek (7 głosów, średnia: 4,43 z 5)
Loading...

13 komentarzy

  1. czarek pisze:

    Nareszcie zrozumiałem tę różnicę. W innych artykułach jedni z drugiego kopiują i nic nie można było zrozumieć. Tutaj pięknie zostało to opisane, dziękuję bardzo.

  2. jo_dariusz pisze:

    Prosto, konkretnie i bardzo zrozumiale. Dzięki za artykuł!

  3. marcin pisze:

    świetny artykuł

  4. Joanna pisze:

    Czyli da się wytłumaczyć i przystępnie, i krótko. Pomogłeś 🙂

  5. szymon pisze:

    Hi,

    dzięki za art. A co myślisz o takich zapisach w sassie. Po co takie funkcje tworzyć – proszę o rozjaśnienie tematu 🙂 Dzięki.

    $base-font-size: 18;

    @function percent($size) {
    $percentSize: $base-font-size / 16 * 100%;
    @return #{$percentSize};
    }

    @function rem($size) {
    $remSize: $size / #{$base-font-size};
    @return #{$remSize}rem;
    }

    ——-

    html {
    font-size: percent(18);
    }

    .component-wrapper__footer {
    font-size: rem(12);
    }

  6. Andrzej pisze:

    Dzięki za zwięzłe i proste wytłumaczenie. Rzadko zdarza się, żeby coś było tak zrozumiałe po pierwszym czytaniu.

  7. Mac pisze:

    Dzięki za świetne wyjaśnienie! Jasno i przejrzyście. Bez zbędnych informacji i masy skomplikowanych przykładów.

  8. Paweł pisze:

    Dzięki, masz talent do tłumaczenia. Nawet kod jest zbędny żeby zrozumieć istotę rzeczy.

  9. Przemek pisze:

    Zrozumiałem! Super, prosto i zwięźle wytłumaczone. Pozdrawiam

  10. karcia53 pisze:

    Wszystkie fajnie, przystępnie opisana różnica, ale jeden szczegół mnie zaskoczył. Piszesz:

    „Jeśli jakiemuś elementowi nadamy szerokość 10 rem i wysokość 5 rem:

    article {
    width: 10rem;
    height: 5rem;
    }
    Element ten będzie mieć 200 px szerokości i 100 px wysokości, ponieważ 20 x 10 = 200 i 20 x 5 = 100.”

    A przecież w znaczniku html określiłeś tylko rozmiar czcionki na 20px i potem względem niego korzystałeś z rem, więc jakim cudem rozmiar czcionki przekłada się teraz na szerokość i wysokość, skoro to zupełnie (jak mi się zdaje) inne parametry? 🙂 Czy przypadkiem jeśli nie zdefiniujemy inaczej, to domyślna szerokość (width) nie wynosi 100%? Tak więc 10rem oznaczałoby 1000% (jakkolwiek to interpretować)?

Skomentuj Mac Anuluj pisanie odpowiedzi

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *