Block Formatting Contexts

This article was first published on YUI Blog (05-19-2010).

A block formatting context is a box that satisfies at least one of the following:

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 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

Section 9.4.1 says that the following will establish new block formatting contexts:

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]).
http://www.w3.org/TR/css3-box/#block-level0

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.
http://www.w3.org/TR/CSS21/conform.html

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:

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:

 float: left;
 width: 160px;
 float: right;
 width: 160px;
 overflow: hidden;
 zoom: 1;
 border-width: 5px;
 border-style: solid;
 border-color: #52E052;

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:

Yes, you’d use 180px, 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 730 pixels (160px + 160px + 400px + 10px).

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.

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-rl
In 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-x and overflow-y (any value other than visible)

Things to consider

In Quirks Mode and IE7 Mode (All Versions)

HTML elements that always have a layout:

In Internet Explorer, these elements have – by default – a layout:

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, clear clears 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

Demos and testcases

haslayout articles

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.