Block formatting context
A block formatting context is a part of a visual CSS rendering of a web page. It's the region in which the layout of block boxes occurs and in which floats interact with other elements.
A block formatting context is created by at least one of the following:
- The root element of the document (
<html>
). - Floats (elements where
float
isn'tnone
). - Absolutely positioned elements (elements where
position
isabsolute
orfixed
). - 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), orinline-table
. - Block elements where
overflow
has a value other thanvisible
andclip
. display
: flow-root
.- Elements with
contain
: layout
,content
, orpaint
. - Flex items (direct children of the element with
display
: flex
orinline-flex
) if they are neither flex nor grid nor table containers themselves. - Grid items (direct children of the element with
display
: grid
orinline-grid
) if they are neither flex nor grid nor table containers themselves. - Multicol containers (elements where
column-count
orcolumn-width
isn'tauto
, including elements withcolumn-count: 1
). column-span
: all
should always create a new formatting context, even when thecolumn-span: all
element isn't contained by a multicol container (Spec change, Chrome bug).
Formatting contexts affect layout, but typically, we create a new block formatting context for the positioning and clearing floats rather than changing the layout, because an element that establishes a new block formatting context will:
- contain internal floats.
- exclude external floats.
- suppress margin collapsing.
Note: A Flex/Grid container(display
: flex/grid/inline-flex/inline-grid) establishes a new Flex/Grid formatting context, which is similar to block formatting context except layout. There's no floating children available inside a flex/grid container, but exclude external floats and suppress margin collapsing still works.
Examples
Contain internal floats
Make float content and alongside content the same height.
Let's have a look at a couple of these in order to see the effect creating a new BFC.
In the following example, we have a floated element inside a <div>
with a border
applied. The content of that <div>
has floated alongside the floated element. As the content of the float is taller than the content alongside it, the border of the <div>
now runs through the float. As explained in the guide to in-flow and out of flow elements, the float has been taken out of flow so the background
and border
of the <div>
only contain the content and not the float.
using overflow: auto
Setting overflow: auto
or set other values than the initial value of overflow: visible
created a new BFC containing the float. Our <div>
now becomes a mini-layout inside our layout. Any child element will be contained inside it.
The problem with using overflow
to create a new BFC is that the overflow
property is meant for telling the browser how you want to deal with overflowing content. There are some occasions in which you will find you get unwanted scrollbars or clipped shadows when you use this property purely to create a BFC. In addition, it is potentially not readable for a future developer, as it might not be obvious why you used overflow
for this purpose. If you use overflow
, it is a good idea to comment the code to explain.
using display: flow-root
A newer value of display
lets us create a new BFC without any other potentially problematic side-effects. Using display: flow-root
on the containing block creates a new BFC .
With display: flow-root;
on the <div>
, everything inside that container participates in the block formatting context of that container, and floats will not poke out of the bottom of the element.
The value name of flow-root
makes sense when you understand you are creating something that acts like the root
element (<html>
element in browser) in terms of how it creates a new context for the flow layout inside it.
HTML
<section>
<div class="box">
<div class="float">I am a floated box!</div>
<p>I am content inside the container.</p>
</div>
</section>
<section>
<div class="box" style="overflow:auto">
<div class="float">I am a floated box!</div>
<p>I am content inside the <code>overflow:auto</code> container.</p>
</div>
</section>
<section>
<div class="box" style="display:flow-root">
<div class="float">I am a floated box!</div>
<p>I am content inside the <code>display:flow-root</code> container.</p>
</div>
</section>
CSS
section {
height:150px;
}
.box {
background-color: rgb(224, 206, 247);
border: 5px solid rebeccapurple;
}
.box[style] {
background-color: aliceblue;
border: 5px solid steelblue;
}
.float {
float: left;
width: 200px;
height: 100px;
background-color: rgba(255, 255, 255, .5);
border:1px solid black;
padding: 10px;
}
Exclude external floats
In the following example, we are using display:flow-root
and floats to implement double columns layout, because an element in the normal flow that establishes a new BFC must not overlap the margin box of any floats in the same block formatting context as the element itself.
HTML
<section>
<div class="float">Try to resize this outer float</div>
<div class="box"><p>Normal</p></div>
</section>
<section>
<div class="float">Try to resize this outer float</div>
<div class="box" style="display:flow-root"><p><code>display:flow-root</code><p></div>
</section>
CSS
section {
height:150px;
}
.box {
background-color: rgb(224, 206, 247);
border: 5px solid rebeccapurple;
}
.box[style] {
background-color: aliceblue;
border: 5px solid steelblue;
}
.float {
float: left;
overflow: hidden; /* required by resize:both */
resize: both;
margin-right:25px;
width: 200px;
height: 100px;
background-color: rgba(255, 255, 255, .75);
border: 1px solid black;
padding: 10px;
}
Rather than inline-blocks with width:<percentage>, in this case we don't have to specify the width of the right div.
Note that flexbox is a more efficient way to implement multi-column layout in modern CSS.
Margin collapsing
Creating a new BFC to avoid the margin collapsing between two neighbor div:
HTML
<div class="blue"></div>
<div class="red-outer">
<div class="red-inner">red inner</div>
</div>
CSS
.blue, .red-inner {
height: 50px;
margin: 10px 0;
}
.blue {
background: blue;
}
.red-outer {
overflow: hidden;
background: red;
}
Specifications
Specification | Status | Comment |
---|---|---|
CSS Display Module Level 3 The definition of 'Block Formatting Context' in that specification. |
Candidate Recommendation | define BFC(abbr) etc. |
CSS Level 2 (Revision 1) The definition of 'Block Formatting Context' in that specification. |
Recommendation | Initial definition. |
See also
float
,clear
- CSS Key Concepts: CSS syntax, at-rule, comments, specificity and inheritance, the box, layout modes and visual formatting models, and margin collapsing, or the initial, computed, resolved, specified, used, and actual values. Definitions of value syntax, shorthand properties and replaced elements.