rem vs em w jednym zagnieżdżonym demo
rem odnosi się do rozmiaru czcionki korzenia (elementu <html>, domyślnie 16px). em odnosi się do bieżącego rozmiaru czcionki, a w przypadku font-size oznacza to rozmiar rodzica. Zagnieźdź tę samą klasę trzy razy, a różnica stanie się widoczna:
Wypisane rozmiary to wartości obliczone przez przeglądarkę. Każde 1.25em mnoży rozmiar rodzica: 20px, potem 25px, potem 31.25px. Każde 1.25rem patrzy tylko na korzeń: 20px, 20px, 20px. Właśnie przez to kumulowanie rozmiary czcionki w em wymykają się spod kontroli w zagnieżdżonych listach i menu, i dlatego większość stron ustawia rozmiary czcionki w rem.
Do czego odnosi się każda jednostka
| Jednostka | Odnosi się do | 1 jednostka domyślnie |
|---|---|---|
px | niczego (piksel CSS) | 1px |
rem | rozmiaru czcionki elementu głównego (html) | 16px |
em | rozmiaru czcionki elementu; dla samego font-size do rozmiaru rodzica | 16px na najwyższym poziomie |
% | zależy od właściwości (patrz niżej) | |
vw / vh | 1% szerokości / wysokości viewportu | |
dvh, svh, lvh | 1% dynamicznej, małej lub dużej wysokości viewportu | |
vmin / vmax | 1% krótszego / dłuższego boku viewportu | |
ch | szerokości znaku "0" w bieżącej czcionce | około pół em |
ex | wysokości litery x w bieżącej czcionce | około pół em |
Piksel CSS to nie piksel urządzenia: na telefonie z ekranem 3x 1px ma szerokość 3 pikseli urządzenia. Na różnych ekranach zachowuje mniej więcej ten sam rozmiar wizualny, dlatego px nadal dobrze sprawdza się przy obramowaniach i cieniach.
em do odstępów, które skalują się z tekstem
em nie służy tylko do rozmiarów czcionki. W padding, margin, width czy border-radius oznacza "tyle razy rozmiar czcionki tego elementu". Dzięki temu jedna klasa przycisku działa w każdym rozmiarze:
Padding każdego przycisku to połowa jego rozmiaru czcionki w pionie i jeden rozmiar czcionki w poziomie, więc wszystkie trzy wyglądają jak ten sam przycisk w trzech rozmiarach. Z paddingiem w px potrzebna byłaby osobna reguła paddingu dla każdego rozmiaru.
Pamiętaj, że przyciski domyślnie nie dziedziczą rozmiaru czcionki strony (przeglądarki nadają kontrolkom formularzy własny), więc środkowy przycisk ma tu w Chrome 13.33px, a nie 16px. Dodaj font: inherit do przycisków i pól input, jeśli mają pasować do strony.
Procenty: zależą od właściwości
% nie ma jednego znaczenia. Każda właściwość określa, z czego liczony jest procent:
| Właściwość | % odnosi się do |
|---|---|
width, max-width, left, right | szerokości rodzica (bloku zawierającego) |
height, top, bottom | wysokości rodzica, i to tylko wtedy, gdy rodzic ma ustawioną wysokość |
padding, margin (wszystkie cztery strony) | szerokości rodzica |
font-size | rozmiaru czcionki rodzica (150% = 1.5em) |
line-height | rozmiaru czcionki samego elementu |
transform: translate() | rozmiaru samego elementu |
width: 50% to 200px, połowa rodzica. padding-top: 5% to 20px: 5% szerokości rodzica, a nie jego wysokości. A height: 50% nic nie robi, bo rodzic nie ma ustawionej wysokości, więc dziecko jest tylko tak wysokie jak jego tekst plus ten padding. Strona o width i height omawia tę zasadę szczegółowo.
vw, vh i pasek adresu na telefonie
1vw to 1% szerokości viewportu, a 1vh 1% jego wysokości. Przydają się w sekcjach na cały ekran i przy płynnych rozmiarach (często wewnątrz clamp()). Na telefonach vh ma haczyk: pasek adresu przeglądarki wysuwa się i chowa podczas przewijania, a 100vh to wysokość bez paska, więc sekcja hero z height: 100vh jest ucięta u dołu, gdy pasek jest widoczny. Nowsze jednostki to naprawiają:
| Jednostka | Używana wysokość |
|---|---|
100vh | duży viewport (paski ukryte) w większości przeglądarek mobilnych |
100svh | mały viewport (paski widoczne): zawsze się mieści |
100lvh | duży viewport, jawnie |
100dvh | dynamiczny viewport: zmienia się, gdy paski się przesuwają |
.hero {
min-height: 100vh; /* fallback for older browsers */
min-height: 100svh; /* fits the screen even with the address bar visible */
}
vw ma własny haczyk: 100vw obejmuje szerokość pionowego paska przewijania, gdy ten pasek zajmuje miejsce (jak w Windows), więc width: 100vw może być szersze niż strona i dodać poziomy pasek przewijania. Używaj width: 100%, gdy chodzi o "całą szerokość rodzica".
ch dla czytelnej długości wiersza
ch to szerokość znaku "0", więc max-width: 65ch ogranicza akapit do mniej więcej 65 znaków w wierszu, co jest wygodną długością do czytania, przy każdym rozmiarze czcionki:
Której jednostki użyć
| Do czego | Użyj | Dlaczego |
|---|---|---|
| Rozmiary czcionki | rem | Spójne wszędzie, uwzględniają ustawiony przez czytelnika rozmiar czcionki |
| Padding i odstępy w komponentach | rem lub em | em, gdy mają rosnąć z tekstem samego komponentu |
| Obramowania, cienkie linie, cienie | px | Mają pozostać cienkie przy każdym rozmiarze czcionki |
| Szerokości layoutu | %, fr, max-width w rem lub ch | Podążają za kontenerem, ograniczają długość wiersza |
| Sekcje na cały ekran | svh / dvh (z vh jako zapasem) | Radzą sobie z paskami adresu na telefonach |
| Płynna typografia | clamp() łączące rem i vw | Rośnie z ekranem w ustalonych granicach |
Dlaczego rem szanuje czytelników, a px nie
Przeglądarki mają ustawienie domyślnego rozmiaru czcionki, z którego korzystają osoby potrzebujące większego tekstu. Zmienia ono rozmiar czcionki korzenia, więc wszystko w rem i em rośnie razem z nim. font-size: 14px zostaje na 14px bez względu na wybór czytelnika. Powiększenie w przeglądarce skaluje też px, ale to na ustawieniu rozmiaru czcionki polega wielu czytelników. To główny powód, by ustawiać rozmiary czcionki w rem.
Niektóre strony ustawiają html { font-size: 62.5%; }, żeby 1rem równało się 10px i łatwiej się liczyło. To nadal uwzględnia ustawienie czytelnika (62.5% tego, co wybrał), ale pamiętaj o czytelnym font-size na body, bo inaczej każdy element bez własnego rozmiaru pokaże tekst 10px.
Częste błędy
- Rozmiary czcionki w
emw zagnieżdżonych elementach. Mnożą się na każdym poziomie. Do rozmiarów czcionki używajrem. height: 50%, które nic nie robi. Rodzic musi mieć ustawioną wysokość, żeby wysokość w procentach zadziałała.- Oczekiwanie, że
padding-top: 10%będzie zależeć od wysokości rodzica. Procenty pionowego paddingu i marginesu liczone są od szerokości rodzica. width: 100vwpowodujące poziomy pasek przewijania. Obejmuje pasek przewijania. Użyj100%.height: 100vhucięte na telefonach. Użyj100svhlub100dvh.- Ustawienie
html { font-size: 12px }. Wartość w px na korzeniu nadpisuje ustawiony przez czytelnika rozmiar czcionki na całej stronie. Zostaw korzeń w spokoju albo użyj procentu.
Najczęściej zadawane pytania
Czym różni się rem od em?
rem odnosi się do rozmiaru czcionki elementu głównego (<html>), więc 1.5rem ma ten sam rozmiar na całej stronie. em odnosi się do rozmiaru czcionki samego elementu (w przypadku font-size do rozmiaru rodzica), więc kumuluje się, gdy elementy są zagnieżdżone.
Ile pikseli ma 1rem?
Domyślnie 16px, bo przeglądarki ustawiają rozmiar czcionki korzenia na 16px. Jeśli użytkownik zwiększy domyślny rozmiar czcionki w ustawieniach przeglądarki albo ustawisz html { font-size: ... }, 1rem zmienia się razem z nim.
Czy do rozmiaru czcionki używać rem czy px?
Do rozmiarów czcionki używaj rem. Uwzględnia domyślny rozmiar czcionki ustawiony przez czytelnika w przeglądarce, który px ignoruje. Powiększenie w przeglądarce skaluje oba, ale nie każdy czytelnik z niego korzysta.
Kiedy używać em zamiast rem?
Używaj em do odstępów, które mają skalować się z tekstem samego elementu, na przykład paddingu przycisku albo rozmiaru ikony obok tekstu. Ta sama klasa wygląda wtedy dobrze przy każdym rozmiarze czcionki. rem stosuj do rozmiarów czcionki i odstępów na poziomie strony, żeby nic się nie kumulowało.
Czym różni się 100vh od 100dvh?
W przeglądarkach mobilnych 100vh to wysokość przy ukrytym pasku adresu, więc sekcja o wysokości 100vh jest wyższa niż widoczny ekran, gdy pasek jest widoczny. 100dvh (dynamiczna wysokość viewportu) podąża za paskiem, gdy się pojawia i znika, a 100svh to zawsze mniejsza wysokość.