aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/guide/css/block_formatting_context/index.html
blob: c2911bfbe033e513994ca6b3dbce5d0673d5b735 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
---
title: Блочный контекст форматирования
slug: Web/Guide/CSS/Block_formatting_context
tags:
  - CSS
  - CSS Basic Concepts
  - Для начинающих
  - Основы
translation_of: Web/Guide/CSS/Block_formatting_context
---
<p>{{ CSSRef() }}</p>

<h2 id="Summary">Описание</h2>

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

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

<ul>
 <li>корневой элемент документа (<code>&lt;html&gt;</code>).</li>
 <li>плавающие элементы (элементы, у которых {{ cssxref("float") }} не равно <code>none</code>)</li>
 <li>абсолютно позиционированные элементы (элементы, значение  {{ cssxref("position") }} которых либо <code>absolute</code>, либо <code>fixed</code>)</li>
 <li>«строчные блоки» (элементы с {{cssxref("display")}}<code>: inline-block</code>)</li>
 <li>ячейки таблицы (элементы с {{ cssxref("display")}}<code>: table-cell</code>, являющимся значением по умолчанию для ячеек таблицы в HTML)</li>
 <li>заголовки таблицы (элементы с {{ cssxref("display")}}<code>: table-caption</code>, являющимся значением по умолчанию для заголовков таблицы в HTML)</li>
 <li>анонимные ячейки таблицы, неявно создаваемые элементами с {{ cssxref("display") }}<code>: table</code><code>table-row</code><code>table-row-group</code><code>table-header-group</code><code>table-footer-group</code> (значения по умолчанию для таблиц, строк таблиц, «шапок», «подвалов» и тел таблиц в HTML соответственно) либо <code>inline-table</code></li>
 <li>элементы, у которых значение свойства {{ cssxref("overflow") }} отличается от <code>visible</code></li>
 <li>{{ cssxref("display") }}<code><a href="https://drafts.csswg.org/css-display/#valdef-display-flow-root">flow-root</a></code></li>
 <li>элементы с {{ cssxref("contain") }}<code>: layout</code><code>content</code> или <code>strict</code></li>
 <li>флекс-элементы (непосредственные потомки элемента с {{ cssxref("display") }}<code>: flex</code> или <code>inline-flex</code>)</li>
 <li>грид-элементы (непосредственные потомки элемента с {{ cssxref("display") }}<code>: grid</code> или <code>inline-grid</code>)</li>
 <li>многоколоночные контейнеры (элементы, у которых {{ cssxref("column-count") }} или {{ cssxref("column-width") }}  не равно <code>auto</code>, включая элементы с <code>column-count: 1</code>)</li>
 <li>{{ cssxref("column-span") }}<code>: all</code> должно всегда создавать новый блочный контекст форматирования, даже если элемент с <code>column-span: all</code> не находится в многоколоночном контейнере (<a href="https://github.com/w3c/csswg-drafts/commit/a8634b96900279916bd6c505fda88dda71d8ec51">изменение в спецификации</a>, <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=709362">баг Chrome</a>).</li>
</ul>

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

<p>Блочные контексты форматирования важны для размещения плавающих элементов (см. {{ cssxref("float") }}) и отмены их обтекания (см.{{ cssxref("clear") }}) . Правила размещения плавающих элементов и сброса обтекания применяются только к элементам внутри одного и того же блочного контекста форматирования. Плавающие элементы не влияют на размещение содержимого внутри других блочных контекстов форматирования, и отмена обтекания распространяется только на плавающие элементы из того же самого контекста форматирования. <a href="/ru/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing">Схлопывание внешних отступов</a> тоже происходит только между блоками из одного и того же блочного контекста форматирования.</p>

<h2 id="Примеры">Примеры</h2>

<h3 id="Как_сделать_плавающему_контенту_и_соседнему_с_ним_контенту_одинаковую_высоту">Как сделать плавающему контенту и соседнему с ним контенту одинаковую высоту</h3>

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

<p>В примере ниже мы имеем плавающий элемент внутри <code>&lt;</code><code>div&gt;</code> с заданным <code>border</code>. Содержимое этого <code>&lt;div&gt;</code> обтекает плавающий элемент. Так как содержимое <code>float</code> выше, чем остальное содержимое, обтекающее его, <code>border</code> элемента <code>div</code> теперь проходит сквозь <code>float</code>. Как объясняется в руководстве <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow">In Flow and Out of Flow</a>, плавающий элемент был исключён из потока элементов, так что фон и граница <code>div</code> включает только его содержимое, но не элемент <code>float</code></p>

<p>{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/float.html", '100%', 720)}}</p>

<h3 id="Использование_overflow_auto">Использование <code>overflow: auto;</code></h3>

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

<p>{{EmbedGHLiveSample("css-examples/flow/formatting-contexts/bfc-overflow.html", '100%', 720)}}</p>

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

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

<h3 id="Использование_display_flow-root">Использование <code>display: flow-root</code></h3>

<div id="flowroot">
<p>Одно из новых значений свойства <code>display</code>  позволяет нам создавать новый блочный контекст форматирования без всяких потенциально проблемных побочных эффектов. Использование <code>display: flow-root</code> как свойство содержащего блока, создаёт новый блочный контекст форматирования.</p>

<h4 id="CSS">CSS</h4>

<div class="hidden">
<pre class="brush: html line-numbers language-html"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>div</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>box<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
    <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>div</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>float<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>I am a floated box!<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>div</span><span class="punctuation token">&gt;</span></span>
    <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>p</span><span class="punctuation token">&gt;</span></span>I am content inside the container.<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>p</span><span class="punctuation token">&gt;</span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>div</span><span class="punctuation token">&gt;</span></span></code></pre>
</div>
</div>

<pre class="brush: css line-numbers language-css"><code class="language-css"><span class="selector token"><span class="class token">.box</span></span> <span class="punctuation token">{</span>
    <span class="property token">background-color</span><span class="punctuation token">:</span> <span class="function token">rgb</span><span class="punctuation token">(</span><span class="number token">224</span><span class="punctuation token">,</span> <span class="number token">206</span><span class="punctuation token">,</span> <span class="number token">247</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
    <span class="property token">border</span><span class="punctuation token">:</span> <span class="number token">5</span><span class="token unit">px</span> solid rebeccapurple<span class="punctuation token">;</span>
    <span class="property token">display</span><span class="punctuation token">:</span> flow-root
<span class="punctuation token">}</span>
<span class="selector token"><span class="class token">.float</span></span> <span class="punctuation token">{</span>
    <span class="property token">float</span><span class="punctuation token">:</span> left<span class="punctuation token">;</span>
    <span class="property token">width</span><span class="punctuation token">:</span> <span class="number token">200</span><span class="token unit">px</span><span class="punctuation token">;</span>
    <span class="property token">height</span><span class="punctuation token">:</span> <span class="number token">150</span><span class="token unit">px</span><span class="punctuation token">;</span>
    <span class="property token">background-color</span><span class="punctuation token">:</span> white<span class="punctuation token">;</span>
    <span class="property token">border</span><span class="punctuation token">:</span><span class="number token">1</span><span class="token unit">px</span> solid black<span class="punctuation token">;</span>
    <span class="property token">padding</span><span class="punctuation token">:</span> <span class="number token">10</span><span class="token unit">px</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></pre>

<div id="flowroot">
<p>{{EmbedLiveSample("flowroot", 200, 200)}}</p>
</div>

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

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

<div class="blockIndicator note">
<p><strong>Примечание:</strong>  <code>display: flow-root;</code> <a href="https://caniuse.com/#search=flow-root">не поддерживается</a> в Safari.</p>
</div>

<h3 id="Схлопывание_границ_margin">Схлопывание границ margin</h3>

<p>Создание нового блочного контекста форматирования предотвращает эффект <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing">схлопывания границ</a> между двумя соседними div:</p>

<h4 id="HTML">HTML</h4>

<pre class="brush: html line-numbers language-html"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>div</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>blue<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>div</span><span class="punctuation token">&gt;</span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>div</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>red-outer<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
  <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>div</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>red-inner<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>red inner<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>div</span><span class="punctuation token">&gt;</span></span>
<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>div</span><span class="punctuation token">&gt;</span></span></code></pre>

<h4 id="CSS_2">CSS</h4>

<pre class="brush: css line-numbers language-css"><code class="language-css"><span class="selector token"><span class="class token">.blue</span>, <span class="class token">.red-inner</span></span> <span class="punctuation token">{</span>
  <span class="property token">height</span><span class="punctuation token">:</span> <span class="number token">50</span><span class="token unit">px</span><span class="punctuation token">;</span>
  <span class="property token">margin</span><span class="punctuation token">:</span> <span class="number token">10</span><span class="token unit">px</span> <span class="number token">0</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>

<span class="selector token"><span class="class token">.blue</span></span> <span class="punctuation token">{</span>
  <span class="property token">background</span><span class="punctuation token">:</span> blue<span class="punctuation token">;</span>
<span class="punctuation token">}</span>

<span class="selector token"><span class="class token">.red-outer</span></span> <span class="punctuation token">{</span>
  <span class="property token">overflow</span><span class="punctuation token">:</span> hidden<span class="punctuation token">;</span>
  <span class="property token">background</span><span class="punctuation token">:</span> red<span class="punctuation token">;</span>
<span class="punctuation token">}</span></code></pre>

<p>{{EmbedLiveSample("Схлопывание_границ_margin", 120, 120)}}</p>

<h2 id="Specifications">Спецификации</h2>

<ul>
 <li><a class="external" href="http://www.w3.org/TR/CSS21/visuren.html#q15">CSS 2.1</a></li>
 <li><a class="external" href="https://drafts.csswg.org/css-display/#block-formatting-context">CSS Display Level 3</a></li>
</ul>

<h2 id="See_Also">Статьи по теме</h2>

<ul>
 <li>{{ cssxref("float") }}, {{ cssxref("clear") }}</li>
 <li>{{css_key_concepts}}</li>
</ul>