Блочный контекст форматирования
===============================

Описание
--------

**Блочный контекст форматирования** — часть механизма отображения веб-страницы в CSS. Это та область, в которой происходит расположение блочных элементов, и в котором плавающие элементы взаимодействуют с другими элементами.

Блочный контекст форматирования создаёт один из следующих способов (методов):

* корневой элемент документа (`<html>`).
* плавающие элементы (элементы, у которых `float` не равно `none`)
* абсолютно позиционированные элементы (элементы, значение `position` которых либо `absolute`, либо `fixed`)
* «строчные блоки» (элементы с `display``: inline-block`)
* ячейки таблицы (элементы с `display``: table-cell`, являющимся значением по умолчанию для ячеек таблицы в HTML)
* заголовки таблицы (элементы с `display``: table-caption`, являющимся значением по умолчанию для заголовков таблицы в HTML)
* анонимные ячейки таблицы, неявно создаваемые элементами с `display``: table`, `table-row`, `table-row-group`, `table-header-group`, `table-footer-group` (значения по умолчанию для таблиц, строк таблиц, «шапок», «подвалов» и тел таблиц в HTML соответственно) либо `inline-table`
* элементы, у которых значение свойства `overflow` отличается от `visible`
* `display``: flow-root`
* элементы с `contain` (en-US)`: layout`, `content` или `strict`
* флекс-элементы (непосредственные потомки элемента с `display``: flex` или `inline-flex`)
* грид-элементы (непосредственные потомки элемента с `display``: grid` или `inline-grid`)
* многоколоночные контейнеры (элементы, у которых `column-count` или `column-width` (en-US) не равно `auto`, включая элементы с `column-count: 1`)
* `column-span` (en-US)`: all` должно всегда создавать новый блочный контекст форматирования, даже если элемент с `column-span: all` не находится в многоколоночном контейнере (изменение в спецификации, баг Chrome).

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

Блочные контексты форматирования важны для размещения плавающих элементов (см. `float`) и отмены их обтекания (см.`clear`) . Правила размещения плавающих элементов и сброса обтекания применяются только к элементам внутри одного и того же блочного контекста форматирования. Плавающие элементы не влияют на размещение содержимого внутри других блочных контекстов форматирования, и отмена обтекания распространяется только на плавающие элементы из того же самого контекста форматирования. Схлопывание внешних отступов тоже происходит только между блоками из одного и того же блочного контекста форматирования.

Примеры
-------

### Как сделать плавающему контенту и соседнему с ним контенту одинаковую высоту

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

В примере ниже мы имеем плавающий элемент внутри `<div>` с заданным `border`. Содержимое этого `<div>` обтекает плавающий элемент. Так как содержимое `float` выше, чем остальное содержимое, обтекающее его, `border` элемента `div` теперь проходит сквозь `float`. Как объясняется в руководстве In Flow and Out of Flow (en-US), плавающий элемент был исключён из потока элементов, так что фон и граница `div` включает только его содержимое, но не элемент `float`.

### Использование `overflow: auto;`

Создадим новый блочный контекст форматирования, который будет содержать в себе плавающий элемент. Раньше обычным способом сделать это было установить `overflow: auto` или другое значение, отличное от значения по умолчанию `overflow: visible`.

Задание `overflow: auto` создало новый блочный контекст форматирования, включающий `float`. Теперь `div` стал мини-слоем внутри нашего слоя. Любые дочерние элементы войдут в него.

Проблема использования `overflow` для создания нового блочного контекста форматирования в том, что свойство `overflow` предназначено для сообщения браузеру как обращаться с переполнением содержимого. Существуют случаи, в которых оно вызовет появление нежелательных скролл-баров или обрезание теней, когда вы используете это свойство только для того, чтобы создать блочный контекст форматирования. Кроме того, оно потенциально делает код менее понятным для следующего разработчика, так как не всегда очевидно, почему использовано `overflow` в данном случае. Если вы используете этот подход, хорошей идеей будет прокомментировать код, чтобы объяснить это.

### Использование `display: flow-root`

Одно из новых значений свойства `display` позволяет нам создавать новый блочный контекст форматирования без всяких потенциально проблемных побочных эффектов. Использование `display: flow-root` как свойство содержащего блока, создаёт новый блочный контекст форматирования.

#### CSS
```

<div class="box">
  <div class="float">I am a floated box!</div>
  <p>I am content inside the container.</p>
</div>
```



```css
.box {
  background-color: rgb(224, 206, 247);
  border: 5px solid rebeccapurple;
  display: flow-root;
}
.float {
  float: left;
  width: 200px;
  height: 150px;
  background-color: white;
  border: 1px solid black;
  padding: 10px;
}
```


С помощью `display: flow-root;` применённом на элементе `<div>`, всё внутри этого контейнера будет участвовать в едином блочном контексте форматирования этого контейнера, и плавающие элементы не будут торчать из нижней части контейнера.

Задание значения `flow-root` имеет смысл тогда, когда вы понимаете, что вы создаёте что-то, что будет действовать так же, как действует корневой `root` элемент (`<html>` в браузерах) в том плане, что он создаёт новый контекст для компоновки потока внутри него.

**Примечание:** `display: flow-root;` не поддерживается в Safari.

### Схлопывание границ margin

Создание нового блочного контекста форматирования предотвращает эффект схлопывания границ между двумя соседними div:

#### HTML


```html
<div class="blue"></div>
<div class="red-outer">
  <div class="red-inner">red inner</div>
</div>
```


#### CSS


```css
.blue,
.red-inner {
  height: 50px;
  margin: 10px 0;
}

.blue {
  background: blue;
}

.red-outer {
  overflow: hidden;
  background: red;
}
```

Спецификации
------------

* CSS 2.1
* CSS Display Level 3
Статьи по теме
--------------

* `float`, `clear`
* Ключевые концепции CSS
    + Синтаксис CSS
    + @-правила
    + комментарии
    + специфичность
    + наследование
    + блочная модель
    + режимы компоновки
    + модели визуального форматирования
    + Схлопывание отступов
    + Значения
        - начальные
        - вычисленные
        - используемые
        - действительные
    + Синтаксис определения значений (en-US)
    + Сокращённые свойства
    + Замещаемые элементы