HTML/CSSMiddleTechnical

В чём разница между единицами em, rem, px, vw и vh в CSS?

px — фиксированные логические пиксели; em — от font-size родителя (каскадируется); rem — от корневого html (стабилен); vw/vh — 1% ширины/высоты вьюпорта, не зависят от шрифтов.

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

CSS предоставляет несколько систем единиц, каждая из которых привязана к разному опорному значению. Понимание этих различий критически важно для создания адаптивных, доступных интерфейсов.

px — абсолютные пиксели

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

.button {
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 8px 16px;
}

em — относительно шрифта родителя

em вычисляется относительно font-size ближайшего родительского элемента (или самого элемента, если речь идёт о свойстве font-size). Из-за каскадирования вложенные элементы накапливают умножение: 1.2em внутри 1.2em даёт 1.44em от корня.

.parent {
  font-size: 20px;
}

.child {
  font-size: 0.8em;  /* = 16px */
  padding: 1em;      /* = 16px (от font-size самого child) */
  margin: 0.5em;     /* = 8px */
}

rem — относительно корня документа

rem (root em) всегда вычисляется относительно font-size элемента html. По умолчанию браузер устанавливает 16px, но пользователь может изменить это в настройках. Именно поэтому rem предпочтителен для типографики и отступов — он уважает пользовательские настройки и не накапливает каскадирование.

html {
  font-size: 16px; /* базовое значение */
}

.heading {
  font-size: 2rem;    /* всегда 32px */
  margin-bottom: 1rem; /* всегда 16px */
}

.small-text {
  font-size: 0.75rem; /* всегда 12px */
}

vw и vh — относительно вьюпорта

vw (viewport width) равен 1% ширины окна браузера. vh (viewport height) — 1% высоты. Эти единицы не зависят ни от родителей, ни от шрифтов, поэтому удобны для полноэкранных секций, адаптивных шрифтов и позиционирования элементов относительно экрана.

.hero {
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.responsive-title {
  /* Шрифт масштабируется от 24px до 64px */
  font-size: clamp(1.5rem, 5vw, 4rem);
}

Сравнительная таблица

  • px — фиксированный размер, предсказуем, но игнорирует пользовательские настройки шрифта
  • em — зависит от родителя, удобен для компонентной масштабируемости (padding/margin пропорциональны шрифту компонента)
  • rem — единственный источник истины (html), идеален для глобальной типографики и пространства
  • vw — адаптируется под ширину экрана, применяется в fluid typography и горизонтальных лейаутах
  • vh — адаптируется под высоту экрана, применяется для fullscreen-секций; на мобильных Safari может включать/исключать адресную строку

Практический пример: адаптивная карточка

:root {
  font-size: 16px;
}

.card {
  width: min(90vw, 400px);  /* не шире 400px и не шире 90% экрана */
  padding: 1.5rem;           /* rem = стабильный отступ */
  font-size: 1rem;
}

.card__title {
  font-size: 1.25rem;        /* 20px */
  margin-bottom: 0.5em;      /* 10px — пропорционально шрифту заголовка */
}

.card__meta {
  font-size: 0.875rem;       /* 14px */
  margin-top: 0.5em;         /* 7px — пропорционально меньшему шрифту */
}

Подводные камни

  • em-каскадирование: при вложенных em на font-size значения перемножаются — легко получить непредсказуемый размер на глубокой вложенности.
  • vh на мобильных: браузеры iOS Safari и некоторые Android-браузеры учитывают динамическую адресную строку, из-за чего 100vh может быть больше видимой области. Используйте dvh (dynamic viewport height) где поддерживается.
  • px и доступность: если задать html { font-size: 16px } жёстко, пользователь не сможет увеличить базовый шрифт через настройки браузера. Используйте font-size: 100% или просто не переопределяйте корневой шрифт без необходимости.
  • vw и полоса прокрутки: 100vw включает ширину полосы прокрутки, что может вызвать горизонтальный скролл. Предпочитайте width: 100% для блоковых элементов.
  • em для padding/margin: если изменить font-size компонента, все em-отступы внутри автоматически масштабируются — это бывает желанным поведением, но может удивить.
  • Смешивание единиц: неконсистентное использование px и rem в одном проекте затрудняет глобальное масштабирование; лучше принять одну конвенцию в команде.
  • clamp() и vw: font-size: 5vw без ограничений — на широких мониторах шрифт вырастет до нечитаемого размера. Всегда ограничивайте с clamp(min, vw, max).

Common mistakes

  • Смешивать «em, rem, px, vw и vh» с похожим механизмом без критерия выбора.
  • Игнорировать риск: неверно оценить границы применения темы «em, rem, px, vw и vh» и получить хрупкое решение.
  • Показывать только синтаксис и не объяснять поведение в runtime или сборке.

What the interviewer is testing

  • Объясняет разные системы измерения для типографики, отступов и размеров viewport.
  • Показывает на примере, как работает: px стабилен в CSS-пикселях, em зависит от font-size текущего элемента, rem от корня, а vw и vh от размеров viewport; выбор влияет на масштабирование и доступность.
  • Называет production-нюанс и граничный случай для темы «em, rem, px, vw и vh».

Sources

Related topics