Пиксели в CSS и относительные единицы измерения

В CSS есть ряд свойств, предполагающих в качестве значений указание определенного размера. Например, свойства font-size, width, margin, padding. Значением для них являются числа, после которых обязательно указываются единицы измерения, которых в CSS большое количество.

Абсолютные единицы измерения (cm – сантиметр и другие) не рекомендуется использовать при верстке веб-документов. Их применяют для шаблонов страниц, которые выводятся на печать.

Для веб-страниц широко используют:

Проценты и em – это относительные единицы измерения. Это значит, что размер 1em или 1% зависит от элемента страницы, от которого он берется. Пиксели можно считать условно абсолютными. Они абсолютны для конкретного экрана, но их размер зависит от самого экрана.

Пиксели в CSS и пиксели (точки) устройства – это не одно и то же. Их размер совпадает только на экранах с низким разрешением. Большинство современных устройств таковыми не являются. Ваш смартфон может иметь разрешение по ширине экрана в 720 точек, но размещенное на веб-странице изображение в 500px уже выйдет за его пределы, потому что 1px проецируется на несколько физических точек экрана.

Чтобы понять, почему в программировании пошли по такому пути, надо учесть, что размер точки на каждом типе экрана свой. Два одинаковых по размеру монитора (например, 24 дюйма по диагонали) могут иметь разное разрешение (например, 1920x1080 и 2560x1440). Понятно, что на втором размер точки будет меньше (ведь точек больше, а диагональ монитора та же). Чтобы изображение в 500px на нем не выглядело заметно меньшим, чем на первом, надо в 1px объединять большее количество экранных точек. Этот процесс скорее всего выполняется операционной системой и может корректироваться настройками.

В таком случае мы могли бы сказать, что пиксель в CSS – это абсолютная единица, так как независимо от экрана она дает приблизительно одинаково воспринимаемый размер элемента. Но все немного сложнее.

Смартфон вы держите в руках близко к глазам, на монитор смотрите с большего расстояния. Если бы, скажем, картинка там и там была одного размера (воспринималась бы нами как-будто она 5x4 реальных сантиметра), то более детально ее рассмотреть можно было бы только на близком расстоянии, то есть со смартфона. К монитору пришлось бы приближаться.

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

Можно сказать, что пиксель, несмотря на свою неопределенность с точки зрения абсолютных размеров, идеальная единица измерения, заключающая в себе оптимизацию под разные устройства. Если мы стилизуем страницу на одном и нам кажется, что все хорошо, вероятно она будет неплохо выглядеть и на другом.

Теперь рассмотрим преимущества и недостатки em (не путайте с одноименным html-элементом). Исторически название данной единицы измерения идет из типографского дела и означает ширину, равную (equal) большой букве M. К реалиям CSS это уже не имеет отношения.

В CSS 1em равен размеру шрифта родительского элемента. Когда свойство наследуется вложенными элементами, в их css-правиле его не объявляют, если хотят оставить размер шрифта без изменения.

На скрине выше документ не содержит своей таблицы стилей. Представление страницы зависит от стилей браузера и его настроек. Примечание: в Google Chrome панель разработчика открывается нажатием Ctrl + Shift + I, ими же закрывается.

По-умолчанию браузер (агент пользователя) для h1 устанавливает размер шрифта в 2em. Для остальных элементов в "таблице стилей агента пользователя" font-size не объявлен. Это значит, что значение свойства равно 1em.

А вот что из себя представляет 1em зависит в том числе от настроек браузера. Если там поменять размер шрифта со "Среднего" на "Крупный", размер букв станет больше.

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

Итак, если мы исходно используем на странице em, размер ее элементов будет зависеть от агента пользователя. Так не будет, если задать размер шрифта в px.

body {
  font-size: 16px;
}

В этом случае элементы страницы станут независимы от того, что предпочел выбрать пользователь в настройках браузера. Если он захочет увеличить текст, то сможет это сделать только путем масштабирования страницы (Ctrl + колесо мыши, Ctrl + 0 – вернуться к исходному масштабу), что увеличит также те элементы, для которых этого не требуется (меню, картинки).

В этом смысле не задавать размеры в px в самых "предковых" элементах может быть предпочтительным (с другой стороны, пользователи редко меняют настройки по-умолчанию). Пиксели следует использовать там, где тонкая адаптация под разные устройства более значима, чем приспособление под настройки пользователя.

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

Обратите внимание, если для body указать размер шрифта в пикселях, а правила для h1 не прописывать, то это не меняет 2em для заголовка от браузера. Элемент body является родительским для h1. Следовательно, второй наследует размер шрифта первого, а значение 2em увеличивает его в два раза. То есть, если для тела документа устанавливается размер шрифта в 16px, то по-умолчанию заголовок будет фактической величиной в 32px.

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

Решить проблему можно, например, задав правило для вложенных списков. Здесь указать 1em для шрифта.

p, ul {
  font-size: 1.15em;
}

ul ul {
  font-size: 1em;
}

Селектор потомка ul ul выбирает из документа неупорядоченные списки, которые вложены в другие неупорядоченные списки. Вложенный список наследует значение 1.15em от внешнего. При этом к нему самому свойство font-size: 1.15em не применяется, так как его перекрывает аналогичное из более специфичного правила, где 1em берется от значения родителя, то есть от 1.15em (1.15 * 1 = 1.15).

Если на странице или сайте много подобных вложении, следует задуматься об использовании похожей на em единице измерения – rem. Буква r обозначает корневой элемент (англ. root). Им является html. Все остальные значения rem вычисляются относительно его значения, а не ближайшего обрамляющего контейнера.

Значение в 1em в селекторе html можно не указывать, оно достается по-умолчанию. В таком случае все значения rem на странице будут вычисляться относительно 1em.

По отношению к размеру шрифта сходно с em действуют проценты. Они вычисляется от размера шрифта родительского элемента. Так значение 200% увеличит размер в 2 раза.

Проценты как единица измерения могут использоваться при создании отзывчивых макетов страницы, когда блочные элементы меняют свой размер в зависимости от ширины окна. При этом проценты вычисляются относительно размера обрамляющего контейнера. Для самого внешнего – это ширина окна.

Код примера:

<!DOCTYPE html>
<html lang="ru">
<head>
<meta name="viewport" 
content="width=device-width, 
initial-scale=1">
<style>
 
html {
  font-size: 1.3em;
}
p {padding: 5px 15px;}
 
header {
  height: 75px;
  background: Cornsilk;
}
 
nav {
  width: 20%;
  float: left;
  background: LightCyan;
  min-height: 90vh;
}
 
main {
  width: 80%;
  float: right;
  background: Aquamarine;
  min-height: 90vh;
}
 
article {
  width: 60%;
  float: left;
  background: LightGrey;
  min-height: 50vh;
}
 
aside {
  width: 40%;
  float: right;
  background: CornflowerBlue;
  min-height: 50vh;
}
 
</style>
</head>
<body>
 
<header><p>Название сайта</p></header>
 
<nav><p>Навигация</p></nav>
 
<main>
  <p>Основное содержимое</p>
 
  <article><p>Статья</p></article>
 
  <aside>
    <p>Дополнительная информация</p>
  </aside>
</main>
 
</body>
</html>

Здесь элемент header занимает всю ширину (100%), так как это блочный элемент, и мы не меняем его ширину.

Элементы nav и main также вложены в body. Но первый занимает 20% его ширины, второй – 80%.

Элементы article и aside находятся внутри main, относительно которого и вычисляется ширина каждого.

Введение в веб-разработку и создание сайтов