px - это фиксированный размер, который не меняется ни при каких обстоятельствах. em считается относительно размера шрифта родителя и накапливается при вложенности. rem всегда считается от корневого элемента страницы (html) и не накапливается, поэтому для font-size его обычно советуют чаще всего.
В этом уроке
Попробуй прямо сейчас: измени html { font-size: 16px; } на 24px - текст в rem и оба em увеличатся, а px останется прежним. Именно так браузер и обрабатывает изменение размера шрифта в настройках пользователя.
px - фиксированный размер
px (пиксель) - абсолютная единица: 16px - это всегда 16px, независимо от того, что происходит вокруг. Это удобно для предсказуемости, но означает, что текст в px не увеличится, даже если читатель специально увеличил размер шрифта в настройках своего браузера.
font-size: 16px; - предсказуемо, но не реагирует на настройки пользователя.
font-size: 14px; для основного текста статьи - слишком мелко и совсем не масштабируется для тех, кому нужен более крупный шрифт.
em - относительно родителя, с накоплением
em считается от размера шрифта родителя. Если у родителя 20px, а у потомка font-size: 2em, у потомка будет 40px. Проблема начинается, когда em в em: каждый вложенный уровень умножает результат ещё раз, и итоговый размер быстро становится непредсказуемым.
font-size: 1.5em; - на одном уровне вложенности предсказуемо: полтора раза от родителя.
.a { font-size: 1.5em; } .a .b { font-size: 1.5em; } .a .b .c { font-size: 1.5em; } - три вложенных em умножаются друг на друга (1.5 x 1.5 x 1.5), и внутренний текст оказывается в 3+ раза крупнее, чем ожидалось.
rem - относительно корня, без накопления
rem всегда считается от font-size корневого элемента html (обычно 16px по умолчанию в браузере), независимо от того, на какой глубине вложенности находится элемент. Поэтому rem не накапливается - 2rem всегда означает "вдвое больше корневого размера", хоть в самом верху страницы, хоть глубоко внутри других блоков.
font-size: 1.5rem; - результат одинаковый на любой глубине вложенности, легко предсказать.
html { font-size: 10px; } в пикселях "для удобного счёта" - жёстко перезаписывает предпочтение пользователя вместо того, чтобы масштабироваться вместе с ним.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| font-size основного текста задан в px | Текст не увеличивается, если читатель увеличил размер шрифта в настройках браузера - проблема доступности | Использовать rem (или em) для font-size текста |
| Вложенные элементы с font-size в em друг в друге | Размер накапливается на каждом уровне вложенности и быстро становится неожиданно большим или маленьким | Использовать rem, если не нужен именно эффект накопления |
| html { font-size: 10px; } в пикселях "для удобного счёта" | Жёстко перезаписывает пользовательскую настройку размера шрифта вместо того, чтобы масштабироваться вместе с ней | Для круглого счёта использовать html { font-size: 62.5%; } - в процентах, а не в пикселях |
| Не учли, что em в font-size считается от родителя, а тот же em в другом свойстве (например padding) того же элемента - уже от собственного font-size | Путаница при расчётах, когда em используется одновременно в font-size и, например, в padding одного и того же элемента | Для font-size конкретно помнить: em берёт размер шрифта родителя, а не свой собственный |
Шпаргалка
| Единица | От чего считается |
|---|---|
| px | Фиксированный размер, ни от чего не зависит: font-size: 16px; |
| em (в font-size) | От размера шрифта родителя: font-size: 1.5em; |
| em (в других свойствах) | От собственного font-size этого же элемента |
| rem | Всегда от корневого элемента html, без накопления: font-size: 1.5rem; |
| Для доступности | font-size текста - в rem/em, а не в px, чтобы слушался настройки браузера |
Коротко: отвечаем на вопросы
Сколько пикселей в 1rem по умолчанию?
По умолчанию браузеры устанавливают корневой размер шрифта в 16px, поэтому 1rem обычно равен 16px - но это именно настройка по умолчанию, и она меняется, если разработчик задал свой font-size у html или читатель изменил размер шрифта в браузере.
Почему для шрифта советуют rem, а не px?
Потому что px не реагирует на настройку размера шрифта в браузере читателя, а rem пересчитывается вместе с ней - это делает текст доступнее для людей, которым нужен более крупный шрифт.