Concept
Block Formatting Context(BFC) is a part of the CSS visual layout. It works in many ways when using the traditional layout mechanism(with position, float and display), in ways that how elements are layouted and rendered. Refer to MDN Block Formatting Context, A block formatting context is created in following situations:
float
is notnone
position
isabsolute
orfixed
display
isinline-block
display: flow-root
- table layout:
display
istable-cell
ortable-caption
,table-row
etc. - flex items and grid items (flex layout and grid layout)
overflow
is notvisible
Usage
BFC is useful for margin-collapse, positioning and clearing of float(Although there are other ways to resolve the float problem). Here list a few situations for applying BFC.
Preventing Margin Collapse
Considering the below code:
<div class="container">
<p>line 1</p>
<p>line 2</p>
<p>line 3</p>
</div>
<style>
.container p {
margin: 10px;
background-color: red;
}
</style>
We will see that the margin of each p
is 10px rather than 20px in browser, because they are in the same BFC and margin will collapse between siblings. If two sibling elements have a different margin, then the larger one decide the margin between them. And if we add a block element nesting the second p
, then you will see that margin will not collapse any more and the margin between the two p
will become the sum of the their margin.
<div class="container">
<p>line 1</p>
<div class="bfc">
<p>line 2</p>
</div>
<p>line 3</p>
</div>
<style>
.container p {
margin: 10px;
background-color: red;
}
</style>
The above code creates a new Block Formatting Context to containing the second p
, which prevent margin collapse between them. Perhaps you may think you have already done that before but without an explanation. That’s correct. BFC is nothing new but good reasoning for your code.
Containing Floating Element
When setting an element to floating, its parent element will not “contain” it in the layout. In such situation we usually use overflow: hidden
to prevent it. This is also the way to create a BFC. See the code below.
<div class="container">
<div class="float">
</div>
</div>
<style>
.container {
border: 1px solid #ccc;
background-color: green;
width: 200px;
/* overflow: hidden; // create BFC */
}
.float {
float: left;
width: 100px;
height: 100px;
background-color: red;
}
</style>
The result is that the container’s height is 0, which seems to the child element get out of the parent element. To make the parent containing the child element again, we will add overflow: hidden
to the container, which create a BFC within the container.
Preventing Text Wrap
When we set a floating img
or div
to text p
, the text will surround it. To seperate them, we could add overflow: hidden
to the text, which also is to create a BFC.
<div class="container">
<div class="float">
</div>
<p class="text">
A block formatting context is created by one of the following:
the root element or something that contains it
floats (elements where float is not none)
absolutely positioned elements (elements where position is absolute or fixed)
inline-blocks (elements with display: inline-block)
table cells (elements with display: table-cell, which is the default for HTML table cells)
table captions (elements with display: table-caption, which is the default for HTML table captions)
anonymous table cells implicitly created by the elements with display: table, table-row, table-row-group, table-header-group, table-footer-group (which is the default for HTML tables, table rows, table bodies, table headers and table footers, respectively), or inline-table
block elements where overflow has a value other than visible
display: flow-root
elements with contain: layout, content, or strict
flex items (direct children of the element with display: flex or inline-flex)
grid items (direct children of the element with display: grid or inline-grid)
multicol containers (elements where column-count or column-width is not auto, including elements with column-count: 1)
column-span: all should always create a new formatting context, even when the column-span: all element isn't contained by a multicol container (Spec change, Chrome bug).
</p>
</div>
<style>
.float {
float: left;
width: 50px;
height: 50px;
background-color: red;
}
.text {
/* overflow: hidden; // it will create BFC, and text will not surround the float block */
}
</style>
CSS3 suggests a new value flow-root
to generate a BFC, but for now few browsers support the it(IE, safari etc do not support).
Reference: Block Formatting Context In CSS.