Все, что вам нужно знать о полях CSS
Свойства margin-top, margin-right, margin-bottom и margin-left были описаны еще в первой версии CSS вместе с сокращенной формой margin для установки сразу всех четырех свойств. Но не все так просто с использованием полей в CSS.
- Блочная модель CSS
- Сворачивание полей
- Смежные элементы одного уровня
- Пустые блоки
- Родительский и первый или последний дочерний элемент
- Сворачиваются только вертикальные поля
- Как предотвратить сворачивание полей
- Создание контекста блочного форматирования
- Flex и Grid-контейнеры
- Организация полей
- Поля в процентах
- Поля, связанные с потоком
- Заключение
Блочная модель CSS
Блочная модель документа описывает, как содержимое, отступы, границы и поля взаимодействуют друг с другом. В CSS1 блочная модель была детализирована с помощью диаграммы ASCII.

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

Определение блочной модели в 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.
В следующем примере используются эти две сокращенные формы. После изменения направления текста в блоке поля следуют за ним.
Заключение
Что мы узнали о полях:
- Понимание того, когда происходит сворачивание полей, поможет решить эту проблему.
- Установка полей только в одном направлении решает многие проблемы.
- Оперирование блочными и встроенными направлениями помогает в ситуациях, когда направление не зависит от режима записи.