So, in the many years in which
floating (itself a workaround due to a lack of a more sanctioned layout tool) has become an integral part of CSS layouts, we have still not been provided with a control, whose primary purpose is float containment.
Authors have become reliant on either replicating a clearing markup element using generated content (borne from author findings), or have found that
overflow:hidden|scroll|auto; applied to the parent, expands the parent’s margin-box to encapsulate the height of the child(ren). In fact, any property/value pair that can establish a new block formatting context (BFC) has the ability to do this. These pairs include:
Although there are a couple of areas in the spec that detail behavioral characteristics of BFCs, the crucial containment behavior can be derived from the Float specification
[...] an element in the normal flow that establishes a new block formatting context (such as an element with ‘overflow’ other than ‘visible’) must not overlap any floats in the same block formatting context as the element itself. If necessary, implementations should clear the said element by placing it below any preceding floats, but may place it adjacent to such floats if there is sufficient space.
A host of potential candidates
Whilst the aforementioned properties are all able to clear child floats, there is a major difference with one property/value pair in particular in the way that it computes an element’s width.
Every property/value pair that has the ability to establish a BFC – apart from
overflow:hidden|scroll|auto – irrecoverably alters a block box’s computed width by applying the ’shrink-to-fit’ algorithm. In theory, we could try to emulate the expand-to-fit computed width of an in-flow block box with something like:
display:inline-block; /* Establish a new BFC, but that applies shrink-to-fit to computed width */
Whilst this would be a plausible solution in the presence of any horizontal padding values, horizontal margins would remain an issue, which leaves
overflow as being the only real solution.
Exploiting a property for it’s side-effect
Since we’re hacking a property purely for the purposes of harnessing a side-effect of it’s BFC-establishing characteristic, we have to contend with it’s primary purpose; controlling the clipping of an element’s content when it overflows that element’s content box.
In the common case where an element (which has a floated sibling) overflows it’s parent and the parent is established as the containing block, one of the overflow mechanisms will be invoked; this is a problem if you require the overflowing content of the containing block to remain visible. The only solution in this case is to ‘revert’ to one of the more traditional workarounds involving placing a clearing pseudo element after the parent’s document tree content. However, this author-invented solution acquires the pseudo element and means it can’t be used for more appropriate presentational purposes.
The crux of the matter is this – we’re being forced to use hacks in order to contain floats. Whilst
float is an arguably adequate layout model for controlling content position amongst siblings (images, text, etc), it’s inadequate as a fundamental layout mechanism.
We’ve already identified that one particular characteristic of a BFC is that it contains floats in the manner that we require, each of the properties also have their own primary behavioral characteristics. So what I think’s needed is a new control which has the primary purpose of float containment in the same manner as a BFC currently does:
Value: auto | contain
Applies to: non-replaced block-level elements
Granted, there are modules in the pipeline that will supersede
float as a layout tool, but these are all still Working Drafts and likely to remain as drafts for a while longer (as far as I know). However, establishing a control that can be used as an interim solution whilst we still have to use floats, would be advantageous.
You can follow the discussion on www-style here (NOTE: the thread spans multiple months)