ДокументацияCSSЕдиницы измерения CSS: px, em, rem, vw, vh, %, ch, clamp()
Начальный 9 мин чтения

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

Единицы измерения в CSS — абсолютные (px) и относительные (em, rem, vw, vh, %), функция clamp(), когда использовать rem а когда px, подходы к типографике.

единицы измеренияpxemremvwvhclampпроцентыCSSразмеры

Абсолютные единицы

.px       { width: 200px; }    /* пиксель — самый частый */
.pt       { font-size: 12pt; } /* пункт (1pt = 1.33px) — для печати */
.cm       { width: 5cm; }      /* сантиметр */
.mm       { width: 50mm; }     /* миллиметр */

px — единственная абсолютная единица, которую вы будете использовать регулярно. Остальные — для печати.

Относительные единицы

em — относительно размера шрифта элемента

.parent {
  font-size: 16px;
}

.child {
  font-size: 1.5em;    /* 24px (16 × 1.5) */
  padding: 1em;        /* 24px (от своего font-size) */
  margin-bottom: 0.5em; /* 12px */
}

Проблема — em вкладываются. Если у родителя font-size: 1.2em, а у ребёнка тоже 1.2em, результат не 1.2× от базового, а 1.2 × 1.2 = 1.44×:

.level-1 { font-size: 1.2em; } /* 19.2px */
.level-2 { font-size: 1.2em; } /* 23.04px (19.2 × 1.2) */
.level-3 { font-size: 1.2em; } /* 27.65px (23.04 × 1.2) */

rem — относительно корневого размера шрифта

rem = root em. Всегда считается от font-size элемента <html>, а не от родителя:

html {
  font-size: 16px; /* по умолчанию в большинстве браузеров */
}

.card {
  font-size: 1.125rem;  /* 18px — от корня, не от родителя */
  padding: 1rem;        /* 16px */
  margin-bottom: 1.5rem; /* 24px */
}

Нет проблемы вложенности — 1.5rem всегда 24px, независимо от глубины.

Когда em, когда rem

  • rem — для font-size, margin, padding на уровне компонентов
  • em — для внутренних отступов и размеров внутри компонента, которые масштабируются вместе с шрифтом
.button {
  font-size: 1rem;       /* фиксированный от корня */
  padding: 0.5em 1.5em;  /* масштабируется с font-size кнопки */
  border-radius: 0.25em;
}

% — проценты от родителя

.parent {
  width: 1000px;
}

.child {
  width: 50%;   /* 500px — от ширины родителя */
}

.full-height {
  height: 100%; /* работает только если у родителя задана высота */
}

% для высоты работает, если вся цепочка предков имеет заданную высоту вплоть до html:

html, body {
  height: 100%;
}

.full-screen {
  height: 100%; /* теперь работает */
}

vw и vh — относительно viewport

.hero {
  height: 100vh;        /* полная высота экрана */
  width: 100vw;         /* полная ширина экрана */
  font-size: 5vw;       /* масштабируется с шириной экрана */
}

.sidebar {
  width: 25vw;          /* четверть экрана */
}

Проблема: 100vw включает ширину скроллбара — может появиться горизонтальная прокрутка. Используйте 100% для ширины или dvw/dvh.

Современные единицы viewport

.full-height {
  height: 100dvh;  /* dynamic viewport height — учитывает мобильную адресную строку */
}

.hero {
  height: 100svh;  /* small viewport height — самый маленький viewport */
}

.modal {
  height: 100lvh;  /* large viewport height — без адресной строки */
}

На мобильных браузерах адресная строка то появляется, то прячется. dvh адаптируется, vh — нет.

ch — ширина символа «0»

.input {
  width: 30ch; /* примерно 30 символов моноширинного текста */
}

p {
  max-width: 65ch; /* оптимальная длина строки для чтения */
}

Удобно для ограничения ширины текстового блока — исследования показывают, что 45-75 символов в строке оптимально для чтения.

Функция calc()

Математические выражения, можно смешивать единицы:

.sidebar {
  width: calc(100% - 250px);
}

.header {
  height: calc(100vh - 64px);
}

.grid {
  grid-template-columns: repeat(3, calc((100% - 2rem) / 3));
}

Функция clamp()

Минимум, предпочтительное значение, максимум:

h1 {
  font-size: clamp(1.5rem, 4vw, 3rem);
  /* минимум 1.5rem, обычно 4vw, но не больше 3rem */
}

.container {
  padding: clamp(1rem, 3vw, 3rem);
  width: clamp(320px, 90%, 1200px);
}

clamp() часто заменяет media queries для типографики и отступов.

min() и max()

.element {
  width: min(500px, 90%);
  /* выберет меньшее: на широком экране 500px, на узком 90% */

  font-size: max(1rem, 2vw);
  /* выберет большее: не меньше 1rem */
}

Рекомендации

ЧтоЕдиница
Font-sizerem
Padding/marginrem или em
Ширина контейнераpx (max-width) или %
Max-width текстаch
Высота секцииvh / dvh
Адаптивные значенияclamp()
Расчётыcalc()
Borderpx
Border-radiuspx или % (50% для круга)
Box-shadowpx
Media queriespx или em

Базовый сброс для работы с rem:

html {
  font-size: 100%; /* 16px — не сбрасывайте до 10px, это ломает доступность */
}

body {
  font-size: 1rem;
  line-height: 1.5;
}

Итог

  • px — абсолютная, для границ, теней, мелких деталей
  • rem — от корневого шрифта, лучший выбор для font-size и отступов
  • em — от шрифта элемента, для масштабируемых компонентов
  • % — от родителя
  • vw/vh — от viewport, dvh для мобильных
  • ch — ширина символа, для max-width текста
  • clamp() — адаптивные значения без media queries
  • calc() — вычисления с разными единицами