Перейти к содержанию
Innovialabs

Единицы измерения в CSS: px, em, rem, %, vw и vh

Основы4 мин

Коротко

px — фиксированный размер, rem считается от корневого шрифта, em — от шрифта родителя, % — от родительского блока, vw и vh — от окна; для шрифтов и отступов удобнее rem, для экрана на мобильных — dvh или svh.

Короткий ответ

В CSS есть абсолютные единицы, которые не зависят от окружения, и относительные, которые считаются от чего-то другого: шрифта, родителя или окна браузера.

ЕдиницаОт чего считаетсяГде удобна
pxФиксированный CSS-пиксельРамки, тени, мелкие детали
remРазмер шрифта корневого элемента htmlШрифты, отступы, размеры компонентов
emРазмер шрифта текущего элемента (для font-size — родителя)Отступы внутри кнопки, иконки рядом с текстом
%Размер родительского блокаШирина колонок, адаптивные блоки
vw / vh1% ширины / высоты окнаПолноэкранные секции, «плавающая» типографика

Важно: CSS-пиксель — не физическая точка экрана. На экранах с высокой плотностью один px занимает несколько физических пикселей, поэтому 16px выглядит примерно одинаково на ноутбуке и телефоне.

rem и em: в чём разница и как em накапливается

По умолчанию в браузерах корневой шрифт обычно 16px, значит 1rem = 16px. Если пользователь увеличил шрифт в настройках браузера, все размеры в rem вырастут вместе с ним — это плюс для доступности. Размеры в px такую настройку игнорируют.

rem всегда считается от одного места — html. em считается от ближайшего контекста, и при вложенности значения перемножаются:

.menu { font-size: 1.2em; }
<ul class="menu">        <!-- 16 × 1.2 = 19.2px -->
  <li>
    <ul class="menu">    <!-- 19.2 × 1.2 = 23.04px -->
      <li>Пункт</li>
    </ul>
  </li>
</ul>

Каждый вложенный уровень становится крупнее — частая причина «необъяснимо огромного» текста. С 1.2rem все уровни были бы одинаковыми.

Зато em полезен там, где размер должен следовать за текстом: padding: 0.5em 1em у кнопки сохраняет пропорции, если поменять ей font-size.

Проценты: от чего именно

% почти всегда считается от родительского блока, но есть нюансы:

  • width: 50% — половина ширины родителя.
  • height: 50% работает, только если у родителя задана высота.
  • padding и margin в процентах считаются от ширины родителя, даже вертикальные.
  • font-size: 120% — то же самое, что 1.2em.

vw, vh и проблема 100vh на мобильных

1vw — 1% ширины окна, 1vh — 1% высоты. Кажется, что height: 100vh даёт ровно один экран. На десктопе это так, но на мобильных браузерах адресная строка и панели то появляются, то прячутся. vh обычно равен высоте окна при скрытых панелях, поэтому при открытой адресной строке низ блока уходит за край, и кнопка внизу экрана оказывается не видна.

Современные единицы решают проблему:

  • svh — малая высота окна, когда все панели видны. Блок гарантированно помещается.
  • lvh — большая высота, когда панели скрыты (как старый vh).
  • dvh — динамическая высота, меняется вместе с панелями.
.hero {
  min-height: 100vh;   /* запасной вариант для старых браузеров */
  min-height: 100svh;  /* надёжно помещается на мобильных */
}

dvh точнее, но при прокрутке блок может менять высоту и «прыгать». Для первого экрана чаще выбирают svh, dvh — для полноэкранных модальных окон.

Ещё одна ловушка: на десктопе 100vw включает ширину полосы прокрутки, поэтому width: 100vw может вызвать горизонтальный скролл. Для полной ширины обычно достаточно width: 100%.

Практическое правило

  • Шрифты — в rem. Для заголовков, которые растут вместе с экраном, — clamp(): font-size: clamp(2rem, 5vw, 4rem).
  • Отступы и размеры компонентов — в rem, внутренние отступы, зависящие от текста, — в em.
  • Раскладка — %, fr в grid, flex; фиксированные ширины в px — только как max-width.
  • Рамки, тени, тонкие линии — в px.
  • Высота экрана — svh или dvh с запасным vh.

Частые ошибки

  • Задавать font-size в em на вложенных компонентах и получать накопление.
  • Жёсткая height в px для блока с текстом — при увеличении шрифта текст вылезает.
  • 100vh для первого экрана на мобильных без svh.
  • Менять корневой размер на 62.5% ради «удобных» rem и забывать, что это ломает сторонние компоненты.

Частые вопросы

rem. Он уважает настройку размера шрифта в браузере, а px её игнорирует. Визуально при стандартных настройках результат одинаковый.

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.