Block Formatting Contexts

Block Formatting Contexts

转自:Block Formatting Contexts

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.

How block formatting contexts flow

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.

What triggers block formatting contexts

ection 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”)
  • elements styled with “display:flex” or “inline-flex” (flex boxes)

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:fixed establishes 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:table does 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), clear does not work the same with display:table as it does with display:table-cell.

A final trigger is the fieldset element. 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).

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 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 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 border or padding to the element.

Block formatting contexts contain floats

I am sure you have heard of the sentence ” a float always contains floats “, or maybe heard of the FNE ( float nearly everything) method. But the basis of this is that floats are 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 float inside a DIV with a blue background, it is styled with margin:20px
This paragraph is a float inside 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 float so 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 clear the previous box. This is often referred to as “self-clearing”, which makes lot of sense considering that block formatting contexts are a normal part of the flow.

Note: clear only 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 - see test case).

Because this behavior is attached to the “border box” (not the “margin box”), to create space (e.g., a 20px gap) between the pink box and its siblings, authors would need to either:

Set a 20px margin on the floats
Set margin values on the pink box greater than the width of 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 the three pixel jog bug.

hasLayout versus block formatting context

As you may have noticed, all previous examples are styled using overflow: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 of overflow in IE < 7.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值