CSS 101: Block Formatting Contexts(BFC)
2012-03-19 15:40
411 查看
原文地址:http://www.yuiblog.com/blog/2010/05/19/css-101-block-formatting-contexts
参考:http://www.zhoumingzhi.com/2010/06/24/intro-block-formatting-context/
http://w3ctech.com/p/1101
A block formatting context is a box that satisfies at least one of the following:
the value of “float” is not “none”,
the used value of “overflow” is not “visible”,
the value of “display” is “table-cell”, “table-caption”, or “inline-block”,
the value of “position” is neither “static” nor “relative”.
When it comes to the visual formatting model (this is how user agents process the document
tree for visual media), block formatting contexts are big players. So it is crucial for CSS authors to have a solid understanding of their relationship
with the flow, floats, clear, and margins.
The positioning scheme to which block formatting contexts belong is normal
flow. Therefore, the “block” of a block formatting context is positioned in the flow of the page as you’d expect with block boxes, inline
formatting of inline boxes, relative
positioning of block or inline boxes, and positioning of run-in boxes. Simply put, they are part of the page flow.
Section 9.4.1 says that the following will establish new block formatting contexts:
floats,
absolutely positioned elements,
inline-blocks,
table-cells,
table-captions,
elements styled with “overflow” (any value other than “visible”)
But according to the CSS level 3 specification, a block formatting context (a “flow root” in CSS3 speak) is created when the following condition is met:
The value of ” position” is neither “static” nor “relative” (see [CSS3POS]).
This definition means that
of absolute positioning (9.6.1) and references in the specification to an absolutely positioned element (or its box) imply that the element’s ” position”
property has the value “absolute” or “fixed” .
Note that
boxes, one of them (with
This is something authors should keep in mind, because even if both styles establish new block formatting contexts (implicitly or explicitly),
with
A final trigger is the
There were browser bugs (Webkit, Mozilla)
that mentioned this, but nothing “official”. Actually, even if fieldsets establish new block formatting contexts in most browsers, as per section 3.2 (UA conformance), authors were not supposed to take this for granted:
CSS 2.1 does not define which properties apply to form controls and frames, or how CSS can be used to style them. User agents may apply CSS properties to these elements. Authors
are recommended to treat such support as experimental. A future level of CSS may specify this further.
Block formatting contexts contain floats because of the way they flow, and per section 9.4.1, they prevent collapsing margins and do not overlap floats:
In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is
determined by the “margin” properties. Vertical margins between adjacent block boxes in a block formatting context collapse.
In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the
presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may
become narrower due to the floats).
Block formatting contexts behave more or less like any block box, apart from these important exceptions:
Vertical margins between adjacent block boxes collapse, but only if they are
in the same block formatting context. In other words, if the adjacent boxes do not belong to the same block formatting context, their margin will not collapse.
Example:
This is a paragraph inside a DIV with a blue background, styled with
This is a paragraph inside a DIV with a blue background, styled with
This is a paragraph inside a DIV with a blue background, it is styled with
Between the two first blue boxes above, the bottom and top margin of the paragraphs collapse (the gap equals 20 pixels, not 40 pixels), but because the last DIV creates a new block formatting context,
the margins of the third paragraph do not collapse, hence they do not “stick out” of the paragraph’s container but instead are part of that block box.
Note: in IE6, without explicit margins the DIV would fail to enclose the margins.
When it comes to collapsing margins, creating a new block formatting context acts the same as applying
the element.
I am sure you have heard of the sentence ” a floatalways contains floats “, or maybe heard of the FNE ( float
nearly everything) method. But the basis of this is that floatsare block formatting contexts, so a better way to formulate this is to say that ” a block formatting context always contains floats “.
Example:
This paragraph is a floatinside a DIV with a blue background, it is styled with
This paragraph is a floatinside a DIV with a blue background, it is styled with
The first paragraph is a floatso it is removed from the flow and its container collapses, hence the background of this container does not show.
The second paragraph is also a float, but it is contained inside a DIV that creates a new block formatting context, hence that container encloses the child’s “margin box”. You should also
note that, unlike with the first paragraph, there is no need to clearthe previous box. This is often referred to as “self-clearing”, which makes lot of sense considering that block formatting contexts are a normalpart of the flow.
Note:
This one is my favorite. According to the spec,
the border-box of a block formatting context must not overlap the margin-box of floats in the same block formatting context as the element itself. What this means is that browsers create implicit margins on block formatting contexts to prevent them
from overlapping the margin-box of floats. For this very reason, negative margins should have no effect when applied to a block formatting context next to floats (WebKit and IE6 have a problem with this though – seetest
case).
Example:
Because this behavior is attached to the “borderbox” (not the “margin box”), to create space (e.g., a 20pxgap) between the pink box and its siblings, authors would need to either:
Set a 20pxmargin on the floats
Set margin values on the pink box greater than the widthof the floats (i.e.,
Yes, you’d use
Because it is the border-box that tries to fit between the floats, not the margin-box. And if I say it tries it is because that container would drop if there was not enough room for it between the two floats.
In other words, if the pink box was given a 400 pixels width, that box should drop when the parent container is narrower than 770 pixels (180px + 180px + 400px + 10px). As a side
note, in a few instances, this behavior appears to be broken in Firefox (at least in v.3.5.9) (i.e., when the above construct is the first child of
case).
Note: the space that shows in IE6 between the pink box and the two floats is due to thethree
pixel jog bug.
As you may have noticed, all previous examples are styled using
while the latter triggers hasLayout in Internet Explorer (IE 5.5/6/7). This is because these renderings are very close ( similarities with
the CSS specs). Like block formatting contexts, elements that are given a layout appear to prevent collapsing margins, to contain floats, and to not overlap floats.
The lists below show that the properties that establish a new block formatting context also trigger hasLayout, at least the ones supported by the browser, with the exception of
IE < 7.
In Internet Explorer 5 and 6
Things to consider
IE 5.0 does not support
to these elements (i.e., IE6 in quirks mode).
hasLayout is also triggered when the layout-flow is different from the parent layout flow (i.e.,
In Quirks Mode and IE7 Mode (All Versions)
When overflowis set to something other than visible, table-cell elements do notestablish new block formatting contexts.
When overflowis set to visible, table-cell elements establish a new block formatting context.
In Internet Explorer, these elements have - by default – a layout.
To reduce the risk of issues between modern browsers and Internet Explorer ( < 8), authors may choose to give a layout to boxes that establish new block formatting contexts. This way the flow is identical, elements escape floats the same way,
the same floats, and margins collapse where expected. Also, authors must pay attention when styling boxes using hasLayout
triggers (i.e.,
Page breaks and block-formatting contexts: Allowed page breaks (13.3.3).
Clearfix and block formatting contexts: Everything you Know about Clearfix is Wrong
Block formating contexts, “hasLayout” – IE Window vs CSS2.1 browsers: simulations.
New block formatting contexts next to floats
On having layout
“HasLayout” Overview
hasLayout Property
Special thanks to Philippe Wittenbergh and Bruno Fassino for finding spec references
when one needs them and to Ingo Chao for giving us the best resource on having layout.
参考:http://www.zhoumingzhi.com/2010/06/24/intro-block-formatting-context/
http://w3ctech.com/p/1101
A block formatting context is a box that satisfies at least one of the following:
the value of “float” is not “none”,
the used value of “overflow” is not “visible”,
the value of “display” is “table-cell”, “table-caption”, or “inline-block”,
the value of “position” is neither “static” nor “relative”.
When it comes to the visual formatting model (this is how user agents process the document
tree for visual media), block formatting contexts are big players. So it is crucial for CSS authors to have a solid understanding of their relationship
with the flow, floats, clear, and margins.
What does the spec say about…
How block formatting contexts flow
The positioning scheme to which block formatting contexts belong is normalflow. Therefore, the “block” of a block formatting context is positioned in the flow of the page as you’d expect with block boxes, inline
formatting of inline boxes, relative
positioning of block or inline boxes, and positioning of run-in boxes. Simply put, they are part of the page flow.
What triggers block formatting contexts
Section 9.4.1 says that the following will establish new block formatting contexts:floats,
absolutely positioned elements,
inline-blocks,
table-cells,
table-captions,
elements styled with “overflow” (any value other than “visible”)
But according to the CSS level 3 specification, a block formatting context (a “flow root” in CSS3 speak) is created when the following condition is met:
The value of ” position” is neither “static” nor “relative” (see [CSS3POS]).
This definition means that
position:fixedestablishes a new block formatting context, too. This is not a miss in section 9.4.1, though; fixed positioning is a subcategory
of absolute positioning (9.6.1) and references in the specification to an absolutely positioned element (or its box) imply that the element’s ” position”
property has the value “absolute” or “fixed” .
Note that
display:tabledoes not establish block formatting contexts per se. But because it can generate anonymous
boxes, one of them (with
display:table-cell) establishes a new block formatting context. In other words, the trigger is the anonymous box, not
display:table.
This is something authors should keep in mind, because even if both styles establish new block formatting contexts (implicitly or explicitly),
cleardoes not work the same
with
display:tableas it does with
display:table-cell.
A final trigger is the
fieldsetelement. Oddly enough, there was no information on www.w3.org about this behavior until the HTML5 specification.
There were browser bugs (Webkit, Mozilla)
that mentioned this, but nothing “official”. Actually, even if fieldsets establish new block formatting contexts in most browsers, as per section 3.2 (UA conformance), authors were not supposed to take this for granted:
CSS 2.1 does not define which properties apply to form controls and frames, or how CSS can be used to style them. User agents may apply CSS properties to these elements. Authors
are recommended to treat such support as experimental. A future level of CSS may specify this further.
What block formatting contexts do
Block formatting contexts contain floats because of the way they flow, and per section 9.4.1, they prevent collapsing margins and do not overlap floats:In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is
determined by the “margin” properties. Vertical margins between adjacent block boxes in a block formatting context collapse.
In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the
presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may
become narrower due to the floats).
Enough with the specs, what does this mean in the real world?
Block formatting contexts behave more or less like any block box, apart from these important exceptions:
Block formatting contexts prevent margin collapsing
Vertical margins between adjacent block boxes collapse, but only if they arein the same block formatting context. In other words, if the adjacent boxes do not belong to the same block formatting context, their margin will not collapse.
Example:
This is a paragraph inside a DIV with a blue background, styled with
margin:20px.
This is a paragraph inside a DIV with a blue background, styled with
margin:20px.
This is a paragraph inside a DIV with a blue background, it is styled with
margin:20px, The parent DIV is styled with
overflow:hidden;zoom:1.
Between the two first blue boxes above, the bottom and top margin of the paragraphs collapse (the gap equals 20 pixels, not 40 pixels), but because the last DIV creates a new block formatting context,
the margins of the third paragraph do not collapse, hence they do not “stick out” of the paragraph’s container but instead are part of that block box.
Note: in IE6, without explicit margins the DIV would fail to enclose the margins.
When it comes to collapsing margins, creating a new block formatting context acts the same as applying
borderor
paddingto
the element.
Block formatting contexts contain floats
I am sure you have heard of the sentence ” a floatalways contains floats “, or maybe heard of the FNE ( floatnearly everything) method. But the basis of this is that floatsare block formatting contexts, so a better way to formulate this is to say that ” a block formatting context always contains floats “.
Example:
This paragraph is a floatinside a DIV with a blue background, it is styled with
margin:20px
This paragraph is a floatinside a DIV with a blue background, it is styled with
margin:20px. The parent DIV is styled with
overflow:hidden;zoom:1.
The first paragraph is a floatso it is removed from the flow and its container collapses, hence the background of this container does not show.
The second paragraph is also a float, but it is contained inside a DIV that creates a new block formatting context, hence that container encloses the child’s “margin box”. You should also
note that, unlike with the first paragraph, there is no need to clearthe previous box. This is often referred to as “self-clearing”, which makes lot of sense considering that block formatting contexts are a normalpart of the flow.
Note:
clearonly clears floats within the same block formatting context.
Block formatting contexts do not overlap floats
This one is my favorite. According to the spec,the border-box of a block formatting context must not overlap the margin-box of floats in the same block formatting context as the element itself. What this means is that browsers create implicit margins on block formatting contexts to prevent them
from overlapping the margin-box of floats. For this very reason, negative margins should have no effect when applied to a block formatting context next to floats (WebKit and IE6 have a problem with this though – seetest
case).
Example:
.sideBar { background: skyBlue; float: left; width: 180px; }
.sideBar { background: yellow; float: right; width: 180px; }
#main { background: pink; overflow: hidden; zoom: 1; border: 5px solid teal; }
Because this behavior is attached to the “borderbox” (not the “margin box”), to create space (e.g., a 20pxgap) between the pink box and its siblings, authors would need to either:
Set a 20pxmargin on the floats
Set margin values on the pink box greater than the widthof the floats (i.e.,
margin:0 220px)
Yes, you’d use
220px, not
20px.
Because it is the border-box that tries to fit between the floats, not the margin-box. And if I say it tries it is because that container would drop if there was not enough room for it between the two floats.
In other words, if the pink box was given a 400 pixels width, that box should drop when the parent container is narrower than 770 pixels (180px + 180px + 400px + 10px). As a side
note, in a few instances, this behavior appears to be broken in Firefox (at least in v.3.5.9) (i.e., when the above construct is the first child of
body– see test
case).
Note: the space that shows in IE6 between the pink box and the two floats is due to thethree
pixel jog bug.
hasLayout versus block formatting context
As you may have noticed, all previous examples are styled usingoverflow:hidden;zoom:1. The former declaration establishes a new block formatting context in modern browsers
while the latter triggers hasLayout in Internet Explorer (IE 5.5/6/7). This is because these renderings are very close ( similarities with
the CSS specs). Like block formatting contexts, elements that are given a layout appear to prevent collapsing margins, to contain floats, and to not overlap floats.
Properties/declarations that give elements a layout
The lists below show that the properties that establish a new block formatting context also trigger hasLayout, at least the ones supported by the browser, with the exception ofoverflowin
IE < 7.
In Internet Explorer 5 and 6
position:absolute
position:fixed
float(any value other than ”
none“)
display:inline-block
width(any value other than ”
auto“)
height(any value other than ”
auto“)
zoom(any value other than ”
normal“)
writing-mode:tb-rl
-ms-writing-mode:tb-rlIn Internet Explorer 7
min-width(any value)
min-height(any value)
max-width(any value other than
none)
max-height(any value other than
none)elements styled with
overflow(any value other than
visible)
overflow-xand
overflow-y(any value other than
visible)
Things to consider
zoomand
writing-modeare proprietary properties and do not validate.
IE 5.0 does not support
zoom
widthand
heighttrigger hasLayout on inline elements only when these properties apply
to these elements (i.e., IE6 in quirks mode).
overflow-xand
overflow-yare part of the CSS3 box model module
hasLayout is also triggered when the layout-flow is different from the parent layout flow (i.e.,
rtlto
ltr)
In Quirks Mode and IE7 Mode (All Versions)
When overflowis set to something other than visible, table-cell elements do notestablish new block formatting contexts.
When overflowis set to visible, table-cell elements establish a new block formatting context.
HTML elements that always have a layout:
In Internet Explorer, these elements have - by default – a layout.<body>(as well as
<html>in Strict mode)
<table>,
<tr>,
<th>,
<td>
<img>
<hr>
<input>,
<button>,
<select>,
<textarea>,
<fieldset>,
<legend>
<iframe>,
<embed>,
<object>,
<applet>
<marquee>
Wrap up
To reduce the risk of issues between modern browsers and Internet Explorer ( < 8), authors may choose to give a layout to boxes that establish new block formatting contexts. This way the flow is identical, elements escape floats the same way, clearclears
the same floats, and margins collapse where expected. Also, authors must pay attention when styling boxes using hasLayout
triggers (i.e.,
width) as such styling may require making that element a new block formatting context as well.
Further readings
Implications
Page breaks and block-formatting contexts: Allowed page breaks (13.3.3).Clearfix and block formatting contexts: Everything you Know about Clearfix is Wrong
Demos and testcases
Block formating contexts, “hasLayout” – IE Window vs CSS2.1 browsers: simulations.New block formatting contexts next to floats
hasLayout articles
On having layout“HasLayout” Overview
hasLayout Property
Special thanks to Philippe Wittenbergh and Bruno Fassino for finding spec references
when one needs them and to Ingo Chao for giving us the best resource on having layout.
相关文章推荐
- 我们常用,却容易忽视——CSS的BFC(Block formatting contexts)
- css Block formatting context BFC
- 什么是CSS BFC(Block Formatting Context)
- CSS BFC(Block Formatting Context)
- CSS BFC(Block Formatting Context)
- CSS之BFC(Block Formatting Context)
- Block Formatting Contexts(块级格式化上下文)
- BFC(Block Formatting Context)
- BFC - Block Formatting Contexts (块级格式化上下文)
- BFC(Block Formatting Context)基础分析
- 【分享】说说标准——CSS核心可视化格式模型(visual formatting model)之四:常规流中的Block formatting context
- BFC(Block Formatting Context)
- BFC(Block Formatting Context)
- Block Formatting Contexts(块级格式化上下文)
- Block Formatting Contexts
- Block Formatting Contexts
- margin折叠及hasLayout && Block Formatting Contexts
- BFC(Block Formatting Context)理解
- CSS布局入门--应用Block Formatting Context
- BFC(Block formatting context)直译为"块级格式化上下文"