Единицы em и rem: относительные размеры и масштабирование интерфейса (CSS)

rem и em — это просто способ задавать размеры не в жёстких пикселях, а «относительно чего‑то». Это нужно, чтобы не править 100 мест в CSS, если надо сделать всё крупнее (или если пользователь сам увеличил шрифт в браузере).


Что такое rem

rem всегда считает от html. Один раз задал font-size на html — и все rem по сайту от него зависят.

css
html { font-size: 16px; }
 
.container {
  padding: 2rem;      /* 32px */
  max-width: 70rem;   /* 1120px */
}

Хочешь сделать интерфейс крупнее — меняешь одну строчку:

css
html { font-size: 18px; }

И всё сразу подстроится: 2rem станет 36px, 70rem станет 1260px. Никаких правок по всему файлу.


Что такое em

em считает от ближайшего родителя, у которого задан font-size.

css
.card {
  font-size: 20px;
}
 
.card p {
  line-height: 1.5em;   /* 30px — потому что 1.5 × 20px */
  margin-bottom: 1em;   /* 20px — потому что 1 × 20px */
}

Здесь em удобен тем, что внутренние отступы и интервалы сразу пропорциональны тексту внутри этого блока. Сделал текст в карточке крупнее — и строки, и отступы стали больше сами.


Где что ставить — по делу, без правил ради правил

Используй rem, когда размер относится к общей сетке и структуре:

  • ширина и высота контейнеров,
  • отступы между крупными секциями,
  • колонки в Grid,
  • высоты хедера/футера.

Пример (подойдёт для форума):

css
.forum-wrapper {
  max-width: 80rem;
  margin: 0 auto;
  padding: 2rem;
}

Используй em, когда размер должен быть «по тексту» внутри элемента:

  • line-height,
  • внутренние padding у кнопок, карточек, абзацев,
  • border-radius (чтобы скругление выглядело пропорционально тексту),
  • отступы внутри списка или блока.

Пример:

css
button {
  font-size: 1rem;
  padding: 0.6em 1.2em;   /* удобно: кнопка «обнимает» текст */
  border-radius: 0.4em;  /* скругление тоже по тексту */
}

Сделаешь кнопку крупнее (font-size: 1.3rem) — и padding, и border-radius сразу станут больше пропорционально. Не надо подбирать новые цифры.


Ловушка с em: вложенность и «снежный ком»

Если ставить em на шрифты во вложенных блоках, размер начинает умножаться:

css
.card { font-size: 1.2rem; }           /* 19.2px при html=16px */
.card ul li { font-size: 0.8em; }     /* 0.8 × 19.2 = 15.36px */
.card ul li span { font-size: 0.9em; }/* 0.9 × 15.36 = 13.824px */

С каждым уровнем текст становится всё мельче. Если не хочешь такого — ставь rem:

css
.card ul li { font-size: 0.85rem; }   /* всегда от html, без нарастания */

Частая ошибка: путают html и body

Многие пишут:

css
.card ul li { font-size: 0.85rem; }   /* всегда от html, без нарастания */

и думают, что rem теперь от body. Нет. rem всегда от html:

css
html { font-size: 16px; }

Если хочешь, чтобы масштаб браузера работал нормально и всё масштабировалось предсказуемо — задавай базу именно на html.


Пример для форума PunBB: карточка поста

css
.post-card {
  padding: 1.5rem;           /* «воздух» вокруг карточки — от общего масштаба */
  border: 1px solid #ccc;
}
 
.post-title {
  font-size: 1.5rem;
  margin-bottom: 0.5rem;    /* отступ под заголовком тоже растёт вместе с ним */
}
 
.post-body p {
  line-height: 1.5em;       /* строки зависят от высоты строки текста */
  margin-bottom: 1em;       /* отступы между абзацами — тоже */
}

Что это даёт на практике:

  • Меняешь html { font-size: ... } — вся карточка пропорционально меняется.
  • Внутри карточки типографика остаётся удобной: строки и отступы подстраиваются под текст.

Про масштаб браузера и доступность

Если всё в px, то при увеличении масштаба в браузере страница просто «приближается» как картинка. Иногда из‑за этого появляются горизонтальные скроллы, элементы наезжают друг на друга, читать неудобно.

Если основные размеры в rem, а внутренние пропорции в em, интерфейс не просто увеличивается — он перестраивается: отступы, высоты, пропорции остаются нормальными. Это и есть нормальная работа с масштабом.

Добавить комментарий