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:
<html>
).
float
isn't
none
).
position
is
absolute
or
fixed
).
display
: inline-block
).
display
: table-cell
, which is the default for HTML table cells).
display
: table-caption
, which is the default for HTML table captions).
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
.
overflow
has a value other than
visible
and
clip
.
display
:
flow-root
.
contain
: layout
,
content
,或
paint
.
display
: flex
or
inline-flex
) if they are neither
flex
nor
grid
nor
table
containers themselves.
display
: grid
or
inline-grid
) if they are neither
flex
nor
grid
nor
table
containers themselves.
column-count
or
column-width
isn't
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
).
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:
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 avaliable inside a flex/grid container, but exclude external floats and suppress margin collapsing still works.
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>
采用
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.
使用
overflow: auto
设置
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.
使用
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.
<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>
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;
}
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.
<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>
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 muti columns layout in morden CSS.
Creating a new BFC to avoid the margin collapsing between two neighbor div:
<div class="blue"></div> <div class="red-outer"> <div class="red-inner">red inner</div> </div>
.blue, .red-inner {
height: 50px;
margin: 10px 0;
}
.blue {
background: blue;
}
.red-outer {
overflow: hidden;
background: red;
}
float
,
clear