Establishing a new method of float containment

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:

  • float:left|right
  • position:absolute|fixed
  • display:inline-block|table-cell|table-caption
  • overflow:hidden|scroll|auto

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.

9.5 Floats

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 */
   width:100%;
   box-sizing:border-box;
}

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.

What’s needed

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:

'float-contain'
Value:       auto | contain
Initial:     auto
Applies to:  non-replaced block-level elements
Inherited:   no

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)

Comments are closed.

Leave your own response
  1. Rob said on:

    I’m wondering why you are looking for a solution to a non-problem. Float does exactly what it’s intended to do and, personally, I’m fine with that.

  2. James Hopkins said on:

    Rob, it appears you’ve missed the point of the post :)

    99.9% of authors require a parent to encapsulate it’s floated child(ren), by default. Unfortunately, without utilizing one of the hacks I speak of in the post, this doesn’t happen. Therefore, the aim of the article is to describe present methods that authors have been forced to adopt in order to achieve their intention, and to also an offer informal proposal in the form of a new control, whose primary attribute is to contain floats in the way that BFCs currently do, whilst exibiting no other behavior. There are other modules that will supersede the float model, so the proposal of a new control should be seen as an interim solution, until it’s realistic for authors to adopt these new modules.

    If you don’t believe there’s an issue, then I suggest participating in one of the current discussions on and voicing your opinion there, too.

  3. Matt Wilcox said on:

    I’ve been thinking we need a dedicated property for this for a while. There are many times when I need to use overflow purely for it’s ability to expand containers around floated elements – but the catch kills designs as I can’t then position things outside of the box without clipping. Even text-shadow succumbs to it.