
Как перевести px в rem (и обратно) в CSS
Почти в каждом CSS-проекте рано или поздно встаёт один и тот же вопрос. Дизайнер
прислал макет в пикселях, а вёрстка должна лежать в rem. Перевести одно
значение несложно, но когда таких значений в макете полсотни, считать в уме
надоедает быстро. Разберём саму формулу, а заодно и то, почему rem стоит
предпочесть px, если макет нужно не просто сдать, но и не сломать при этом
доступность сайта.
Быстро прогнать весь список значений можно в конвертере px в rem. Но понимать, что происходит внутри, всё же полезно.
Формула
Обе единицы связаны через один параметр, базовый размер шрифта корневого
элемента (<html>). По умолчанию браузеры ставят его в 16px.
Если в проекте другая база, скажем дизайн-система живёт на 14px, подставьте её вместо шестнадцати. Больше нигде в формуле ничего не меняется.
Таблица соответствий при базе 16px
Значения, которые встречаются в вёрстке чаще всего:
| px | rem | Где применяется |
|---|---|---|
| 4px | 0.25rem | Мелкий отступ, зазор между иконкой и текстом |
| 8px | 0.5rem | Внутренний отступ компактных элементов |
| 12px | 0.75rem | Подписи, вспомогательный текст |
| 14px | 0.875rem | Мелкий текст интерфейса |
| 16px | 1rem | Базовый размер текста |
| 20px | 1.25rem | Крупный текст, подзаголовок |
| 24px | 1.5rem | Заголовок третьего уровня, отступ секции |
| 32px | 2rem | Заголовок, крупный отступ |
| 48px | 3rem | Отступ между блоками страницы |
| 64px | 4rem | Крупный заголовок, отступ секции |
Чем rem отличается от em
rem всегда считается от корневого элемента (<html>), а em от размера
шрифта родителя. Разница вылезает при вложенности: em накапливается, rem
нет.
Для типографики и отступов почти всегда берут rem, он предсказуем и не зависит
от того, во сколько вложенных блоков попал элемент. em остаётся полезен там,
где размер должен зависеть от текста рядом. Скажем, внутренний отступ кнопки,
который сам подстраивается под кегль надписи внутри неё.
Зачем вообще rem вместо px
Причина сугубо практическая. Пользователи меняют базовый размер шрифта в
настройках браузера, если стандартные 16px им мелко читать. Размеры в rem
подхватывают эту настройку автоматически: вырастет текст, вырастут и завязанные
на него отступы. Размеры в px жёстко зафиксированы и не реагируют вовсе, так
что сайт для такого человека останется мелким, что бы он ни ставил в настройках.
Это самая частая причина жалоб на «слишком мелкий шрифт», и лечится она заменой единицы измерения, а не увеличением конкретного значения.
При этом px никуда не девается. Границы в 1px, тонкие разделители и размеры
иконок масштабировать не нужно, там абсолютная точность важнее отзывчивости.
Смешивать единицы в одном проекте нормально, если в каждом месте понятно, почему
выбрана именно эта.
Шрифт, который тянется за экраном
Фиксированный rem хорош для постоянного размера. Но если текст должен плавно
меняться вместе с шириной окна, как заголовок на лендинге, одного rem мало.
Для этого есть функция clamp(), она задаёт минимум, желаемое значение и
максимум одной строкой.
Здесь есть тонкость. Если желаемое значение состоит из чистого vw без
rem-слагаемого, размер перестаёт реагировать на масштабирование браузера, а
это ровно та проблема доступности, которую решает сам rem. Собрать корректный
clamp() с первого раза, без арифметики в столбик, поможет
калькулятор clamp, а подробности есть в
отдельном руководстве по clamp().
Частые ошибки
- Жёсткий
pxна корневом<html>. Убивает пользовательский зум: браузер масштабирует размер шрифта корня, аremуже не реагирует. - Смешивание баз в разных компонентах. Если часть вёрстки завязана на 16px, а
часть на изменённый
font-sizeкорня, одинаковыйremв разных местах даёт разный результат. База должна быть одна на весь проект. - Перевод «на глаз». 15px — это не 1rem и не 0.9rem, а 0.9375rem. Мелкие расхождения незаметны на одном элементе, но накапливаются в сетке из десятков.
Конвертер px, rem и em
Переведите rem в px или px в rem: введите значение, задайте базовый размер шрифта — результат посчитается сразу.
Попробовать
Итог
rem напрямую влияет на доступность сайта, а не просто выглядит современнее.
Формула перевода простая (px ÷ 16), таблица под рукой закрывает частые
значения, а для больших макетов быстрее прогнать список через конвертер выше,
чем считать каждое число руками.



