Все, что вам нужно знать о полях CSS

Свойства margin-top, margin-right, margin-bottom и margin-left были описаны еще в первой версии CSS вместе с сокращенной формой margin для установки сразу всех четырех свойств. Но не все так просто с использованием полей в CSS.

Блочная модель CSS

Блочная модель документа описывает, как содержимое, отступы, границы и поля взаимодействуют друг с другом. В CSS1 блочная модель была детализирована с помощью диаграммы ASCII.

Блочная модель CSS

Схема построения блочной модели CSS

В CSS1 были определены четыре свойства поля для каждой стороны и сокращенная форма записи margin.

Спецификация CSS2.1 определяет термины, которые мы используем для описания различных блоков. Эта спецификация описывает content box, padding box, border box, и margin box. Каждый из этих блоков определяется краями содержимого, отступом, границе и полем.

Блочная модель CSS - 2

Определение блочной модели в CSS2

Сейчас в качестве проекта существует третья спецификация блочной модели. Эта спецификация ссылается на CSS2, поэтому ее мы и будем использовать.

Сворачивание полей

В CSS1 также определялось сворачивание вертикальных полей. Но оно стало причиной многих проблем. При сворачивании полей двух элементов расстояние между ними приравнивается к размеру поля большего из них. Меньшее поглощается большим.

Поля сворачиваются при использовании следующих элементов:

  • Смежных элементов одного уровня.
  • Пустых блоков.
  • Родительский и первый (последний) дочерний элемент.

Смежные элементы одного уровня

В приведенном ниже примере есть три элемента div. Первый имеет верхнее и нижнее поле в 50 пикселей, второй - 20 пикселей, третий - в 3em. Поле между первыми двумя элементами равно 50 пикселей, так как меньшее значение margin-top объединяется с большим нижним.

Поле между вторым и третьим блоком будет иметь величину в 3em. Потому что 3em больше, чем 20 пикселей.

Пустые блоки

Если блок пуст, то его верхнее и нижнее поле сворачиваются. В следующем примере элемент с классом empty имеет верхнее и нижнее поле в 50 пикселей. Но пространство между первым и третьим элементами составляет не 100 пикселей, а 50. Это происходит из-за сужения двух полей. Добавление к этому блоку отступа приведет к отображению верхнего и нижнего полей.

Родительский и первый или последний дочерний элемент

В следующем примере для div с классом wrapper задана красная граница. Три его дочерних div имеют отступ 50 пикселей. Но первый и последний элементы находятся на одном уровне с краями родительского контейнера. Поэтому между ними нет поля в 50 пикселей.

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

Родительский и первый или последний дочерний элемент

Инструменты разработчика помогают увидеть, где заканчивается поле

Сворачиваются только вертикальные поля

В CSS2 сворачиваются только верхние и нижние поля элемента. Таким образом, левые и правые поля не сворачиваются и не оказываются вне оболочки.

Как предотвратить сворачивание полей

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

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

В приведенном ниже примере я добавила для поля отступ в 1px. Теперь у нас есть поле в 50 пикселей сверху и снизу.

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

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

Создание контекста блочного форматирования

Контекст блочного форматирования (BFC) предотвращает сворачивание полей элемента. Если в примере с первым и последним дочерним элементом, поля которых заканчиваются за пределами оболочки, установить для контейнера display: flow-root, поля останутся внутри. С помощью этого значения мы создали новый BFC.

Изменение значения свойства overflow на auto даст тот же эффект. Так как это тоже создаст новый BFC.

Flex и Grid-контейнеры

Flex и Grid-контейнеры устанавливают BFC для своих дочерних элементов. Поэтому они по-другому задают поведение блочного макета и поля не сворачиваются.

Если в приведенном выше примере преобразовать контейнер во Flex, отображающий элементы с помощью flex-direction: column, то поля будут размещаться внутри оболочки. При этом поля между смежными Flex-элементами не сворачиваются друг с другом. Поэтому мы получим расстояние в 100 пикселей между ними.

Организация полей

Последовательная обработка полей поможет избавиться от сворачивания. Для этого нужно определить поля только сверху или только снизу элементов. Благодаря этому сторона с полем всегда будет соседствовать со стороной без поля.

Идеальным решением проблемы является указание элементам display: flow-root. В качестве запасного варианта для устаревших браузеров можно использовать overflow для создания BFC, преобразование родительского элемента во Flex-контейнер или добавление отступа величиной в один пиксель. Не забывайте, что вы можете использовать запросы функций для определения поддержки display: flow-root, чтобы менее оптимальное решение предоставлялось только для устаревших браузеров.

Поля в процентах

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

В приведенном ниже примере внутри контейнера шириной в 200 пикселей определен блок с полем 10%. То есть, 20 пикселей.

Поля, связанные с потоком

Когда мы работаем с логическими, связанными с потоком направлениями, легче говорить о начале и конце блока, а не о верхнем и нижнем крае. Чтобы упростить это, CSS ввел спецификацию «Логические свойства и значения». Она сопоставляет свойства, связанные с потоком, и физические свойства.

Для полей это дает следующие соответствия:

  • margin-top= margin-block-start;
  • margin-right= margin-inline-end;
  • margin-bottom= margin-block-end;
  • margin-left= margin-inline-start.

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

  • margin-block.
  • margin-inline.

В следующем примере используются эти две сокращенные формы. После изменения направления текста в блоке поля следуют за ним.

Заключение

Что мы узнали о полях:

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

Вадим Дворниковавтор-переводчик статьи «Everything You Need To Know About CSS Margins»

Пожалуйста, оставляйте ваши отзывы по текущей теме статьи. За комментарии, отклики, дизлайки, подписки, лайки огромное вам спасибо!