Относительные единицы измерения

Вступление

Про историю единиц измерения можно очень многое рассказать, только пиксели чего стоят.

Пиксель (px) — первая единица измерения в HTML и CSS, базовая, абсолютная и окончательная.

С одной стороны, пиксель это самая распространенная единица измерения в веб, но не самая удобная. Конечно, если у вас простой ленд, сверстан по макету дешевого дизайнера, то пиксели — это единственный правильный вариант добавления размеров. Но в более-менее хорошем макете использование других единиц измерения значительно упростит разработку и поддержку сайта.

Давайте посмотрим, какие вообще есть единицы измерения в веб?

  • px — пиксели
  • cm — сантиметры
  • mm — миллиметры
  • em — ем
  • rem — рэм
  • ch — ширина символа «0»
  • vh — вьюпорт хейт
  • vw — вьюпорт видс
  • vmin — вьюпорт мин
  • vmax — вьюпорт макс

И это не полный список.

Сегодня расскажу, какую пользу можно получить при использовании относительных единиц измерения.

видео

Относительные единицы измерения

Использование em и rem

Обе единицы отлично подходят для типографики. Начну с em.

Допустим, размер шрифта основного текста на мобильной версии 16px, а на десктопе 18px.

Рассмотрим заголовок первого уровня (h1). Размер шрифта которого 2em и отступы 0.67em. Это значит, что размер шрифта заголовка будет в два раза больше основного текста: 16px * 2em = 32px. Отступы тоже можно рассчитать: 32px * 0.67em = 21.44px.

Когда срабатывает переключение сайта на десктопную версию и увеличивается размер основного шрифта, размеры заголовка тоже меняются. font-size = 18px * 2em = 36px. margin-bottom = 36px * 0.67em = 24.12px.

При масштабировании экрана размер заголовка стал больше.

А что это означает? Всё просто: чем больше размер шрифта у основного текста, тем больше размер шрифта и отступы у заголовка. При этом все размеры увеличиваются пропорционально основному тексту. А это значит, что страница сайта будет выглядеть гармоничнее при разных размерах шрифта.

Как правило, я использую такой подход. Он очень удобен, так как не приходится по всему макету изменять размеры шрифта и отступы при изменении размера экрана пользователя. Достаточно изменить размер текста у body. Это значительно увеличивает скорость разработки и поддержки сайта.

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

С одной стороны, для таких элементов можно использовать пиксели. Но это не самый лучший подход. Пользователь может увеличить размер шрифта на своём устройстве или в браузере. В таком случае мы должны пользователю показать элемент крупнее, чем для остальных пользователей. А как определить, на сколько пользователь увеличил шрифт? На сколько нужно увеличить элемент?

В подобных случаях браузер меняет font-size у элемента html. По умолчанию это значение 16px. Если мы будем использовать вместо пикселей rem для всех размеров нашего элемента, то вопрос будет решён.

После изменения размеров шрифта в браузере, параграф с текстом 1rem увеличился в размере.

Чтобы лучше понять разницу между rem и em, попробуйте изменять размер в этом интерактивном блоке.

Интерактивная демонстрация

Измените базовый размер шрифта у интерактивного болока, чтобы увидеть разницу между em и rem:

EM-элемент

Этот элемент использует em. Меняются размеры текста, полей и отступов

REM-элемент

Этот элемент использует rem. Размеры текста, полей и отступов всегда одинаковые

Таким образом, используя em и rem, мы не только значительно упрощаем работу над проектом, но и повышаем доступность сайта.

ch

1ch равен ширине символа «0». На первый взгляд бесполезная штука. Но давайте рассмотрим такое задание: есть поле ввода номера телефона в формате +7 (XXX) XXX-XX-XX. Нужно сделать ширину этого поля так, чтобы номер телефона всегда вмещался без обрезания и без лишних пустых мест.

Решение:

CSS

<input type="tel" name="phone" class="input-phone" placeholder="+7 (XXX) XXX-XX-XX">

CSS

.input-phone {
  width: 18ch;
  font-family: monospace;
  padding: 0.5em;
}
Скриншет поля ввода номера телефона
Ширина синей области (контентной части) равна точно ширине восемнадцати символам.

Свойство font-family: monospace добавлено не случайно. В обычных шрифтах разные символы имеют разную ширину — например, цифра «1» занимает меньше места, чем буква «Ш». В моноширинных шрифтах все символы, включая пробелы, имеют одинаковую ширину. Это гарантирует, что при любом размере текста поле ввода будет идеально вмещать номер телефона — без обрезания символов и без лишнего пустого пространства.

Проценты

Как правило, процент используется для построения сеток. Например, можно сделать блок шириной и высотой 50% от размеров родительского элемента.

Проценты (%)

Проценты рассчитываются относительно размера родительского элемента

50% ширины и высоты родителя

css

.parent {
  width: 100%;
  height: 200px;
}

.child {
  width: 50%;
  height: 50%;
}

При добавлении ширины и высоты элементам учитывайте, что свойства width и height применяются к контентной области элемента.

Скриншет блоковой модели из девтулз браузера
Синяя часть предназначена для контента. Свойства width и height применяются именно к ней.

Если есть поля или обводки, то визуально размер блока будет больше. Чтобы решить этот вопрос, можно рассчитать размеры с учетом полей и обводки.

CSS

.block-1 {
  width: calc(150px - 10px - 10px - 5px - 5px);
  height: calc(150px - 10px - 10px - 5px - 5px);
  margin: 5px;
  padding: 10px;
  border: 5px solid transparent;
}
Скриншет блоковой модели из девтулз браузера
Теперь ширина и высота элемена 150px.

Также можно поменять поведение этих свойств с помощью box-sizing.

CSS

.block-1 {
  width: 150px;
  height: 150px;
  margin: 5px;
  padding: 10px;
  border: 5px solid transparent;
  box-sizing: border-box;
}
Скриншет блоковой модели из девтулз браузера
Свойство box-sizing: border-box; меняет модель расчета ширины и высоты с учетом padding и border.

Свойство box-sizing: border-box следует применять выборочно, только к тем элементам, где это действительно необходимо. В некоторых ситуациях его использование может нарушить верстку. Например, для поля ввода номера телефона должно оставаться стандартное поведение content-box. Если это свойство не было изменено глобально, то явно указывать его не нужно.

HTML

<input type="tel" name="phone" class="input-phone" placeholder="+7 (XXX) XXX-XX-XX">

CSS

.input-phone {
  width: 18ch;
  font-family: monospace;
  padding: 0.5em;
  box-sizing: border-box;
}
Скриншет поля ввода номера телефона
Не все символы отображаются корректно. Применение свойства box-sizing: border-box; изменило способ расчета размеров, в результате чего контентная область стала меньше восемнадцати символов.

Также можно задавать значения для некоторых других свойств в процентах. Например, размер шрифта. В таком случае процент будет работать как em.

Магия vw, vh, vmin, vmax

Когда я изучал верстку, мне поставили задачу: нужно сделать блок, ширина и высота которого должна быть в половину размеров вьюпорта. При этом блок может находиться не только непосредственно в body, но и в его дочерних элементах, со своими размерами, полями, отступами и рамками. На тот момент необходимо было использовать JavaScript. Сейчас такому блоку можно задать размеры в стилях в две строки:

css

.elem {
  width: 50vw;
  height: 50vh;
}

После этого мне усложнили задачу: сделать блок с такими же условиями, но ширина и высота должны быть равны.

css

.elem {
  width: 50vmin;
  height: 50vmin;
}

С помощью vw, vh, vmin и vmax можно получать размеры относительно размеров окна, даже если элемент находится в любом дочернем блоке. Действительно магические единицы.

Как они работают?

1vw — это 1% ширины окна пользователя. 100vw — это 100% от ширины окна пользователя. 1vh работает также, но относительно высоты окна.

1vmin равен 1% от меньшего размера ширины или высоты окна. То есть, если размеры окна пользователя 1920×1080px, то 1vmin = 1% от высоты экрана. То есть 1% от 1080px = 10.8px. vmax работает аналогично vmin, но выбирает большую сторону: 1% от 1920px = 19.2px.

Есть хороший пример для использования vmax. Как сделать, чтобы заголовок всегда был крупным размером шрифта относительно размеров экрана?

css

.hero-title {
  font-size: 8vmax; /* Размер шрифта = 8% от большей стороны вьюпорта */
  text-align: center;
  margin: 0;
}
Размер шрифта зависит от размеров экрана, но не зависит от ориентации мобильного устройства.

На десктопе (1920×1080): 1vmax = 19.2px (1% от ширины 1920px)

На телефоне (портрет, 375×667): 1vmax = 6.67px (1% от высоты 667px)

Специфичный fr

С приходом гридов появилась ещё одна единица — fr (фракция). Фракция используется для построения сетки ячеек на гридах. Например, grid-template-columns: 1fr 2fr;. Вторая колонка всегда будет вдвое больше первой. При этом обе колонки займут всю доступную ширину.

В данном случае задается размер ячейке, а не элементу. Поэтому не будут учитываться поля, обводки и даже отступы.

Скриншет грид блока с двумя дочерними элементами и открытым девтулз
Вторая ячейка вдвое больше первой. Из-за свойства margin: 5px; второй блок не заполняет всю ячейку.

Эта единица доступна только для CSS Grid Layout.

Другие единицы измерения

Оставшиеся единицы измерения используются реже. Подробно про них рассказывать не буду. Интересно, что все точные единицы менялись со временем. Это происходило из-за развития технологий. Изначально один пиксель был одной точкой монитора, а сейчас разрешение экрана мобильного устройства выше, чем на мониторе на заре развития компьютеров.

Но всё же некоторые единицы измерения могут пригодиться. Например, я верстал визитки, используя миллиметры (mm).

css

.business_card {
  width: 90mm;
  height: 50mm;
  /* остальной код */
}

Итоги

Использование относительных единиц измерения значительно упрощает работу над проектом:

  • Используя проценты или vw с vh, легче сделать резиновую верстку
  • rem повышает доступность контента и упрощает верстку
  • em сокращает большое количество кода. Достаточно у body изменить размер шрифта, и на всём сайте размеры изменятся пропорционально
  • Некоторые единицы измерения помогают просто решать сложные вопросы
  • Другие единицы измерения позволяют решать бытовые или узкоспециализированные задачи, но их точность может меняться
Объявление

Нравится фронтенд — попробуйте самые подробные интерактивные тренажёры от HTML Academy бесплатно. Подойдут и действующим разработчикам, чтобы подтянуть навыки вёрстки.