rem и em — это просто способ задавать размеры не в жёстких пикселях, а «относительно чего‑то». Это нужно, чтобы не править 100 мест в CSS, если надо сделать всё крупнее (или если пользователь сам увеличил шрифт в браузере).
Что такое rem
rem всегда считает от html. Один раз задал font-size на html — и все rem по сайту от него зависят.
html { font-size: 16px; } .container { padding: 2rem; /* 32px */ max-width: 70rem; /* 1120px */ }
Хочешь сделать интерфейс крупнее — меняешь одну строчку:
html { font-size: 18px; }
И всё сразу подстроится: 2rem станет 36px, 70rem станет 1260px. Никаких правок по всему файлу.
Что такое em
em считает от ближайшего родителя, у которого задан font-size.
.card { font-size: 20px; } .card p { line-height: 1.5em; /* 30px — потому что 1.5 × 20px */ margin-bottom: 1em; /* 20px — потому что 1 × 20px */ }
Здесь em удобен тем, что внутренние отступы и интервалы сразу пропорциональны тексту внутри этого блока. Сделал текст в карточке крупнее — и строки, и отступы стали больше сами.
Где что ставить — по делу, без правил ради правил
Используй rem, когда размер относится к общей сетке и структуре:
- ширина и высота контейнеров,
- отступы между крупными секциями,
- колонки в Grid,
- высоты хедера/футера.
Пример (подойдёт для форума):
.forum-wrapper { max-width: 80rem; margin: 0 auto; padding: 2rem; }
Используй em, когда размер должен быть «по тексту» внутри элемента:
line-height,- внутренние
paddingу кнопок, карточек, абзацев, border-radius(чтобы скругление выглядело пропорционально тексту),- отступы внутри списка или блока.
Пример:
button { font-size: 1rem; padding: 0.6em 1.2em; /* удобно: кнопка «обнимает» текст */ border-radius: 0.4em; /* скругление тоже по тексту */ }
Сделаешь кнопку крупнее (font-size: 1.3rem) — и padding, и border-radius сразу станут больше пропорционально. Не надо подбирать новые цифры.
Ловушка с em: вложенность и «снежный ком»
Если ставить em на шрифты во вложенных блоках, размер начинает умножаться:
.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:
.card ul li { font-size: 0.85rem; } /* всегда от html, без нарастания */
Частая ошибка: путают html и body
Многие пишут:
.card ul li { font-size: 0.85rem; } /* всегда от html, без нарастания */
и думают, что rem теперь от body. Нет. rem всегда от html:
html { font-size: 16px; }
Если хочешь, чтобы масштаб браузера работал нормально и всё масштабировалось предсказуемо — задавай базу именно на html.
Пример для форума PunBB: карточка поста
.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, интерфейс не просто увеличивается — он перестраивается: отступы, высоты, пропорции остаются нормальными. Это и есть нормальная работа с масштабом.
