Box Model and Floating Elements

In the past years, the box model continuously caused many discussions and frictions among web designers and developers. As an occasional web developer, i used to spend many hours to find a solution for simple problems that i didn’t even bother about in the past….in the past, where web design was about using frames, tables and lots of other old-dated stuff. With responsiveness, adaptability, mobile development a lot of new features of HTML and CSS became available, but browser vendors implemented specifications in different manners and made web development a lot more complicated.

In this article, i would like to point out some important aspects about the use of floating elements and the box model addressing the following (simple) challenges i had way to often:

  • Challenge 1: Parent element of floating elements collapses
  • Challenge 2: Modify the vertically alignment of floating elements within a box
  • Challenge 3: Centering floating elements within a parent box does not work

In the following, i will share and discuss some solutions i collected for these challenges over the years.

Challenge 1: Parent element of floating elements collapses

The problem:

HTML:
<div class="box1">
    <ul>
        <li class="float box2">One</li>
        <li class="float box2">Two</li>
        <li class="float box2">Three</li>
    </ul>
</div>

CSS:
.float {
    float: left;
    margin-right: 0.5em;
}

[..and some formatting of ul, box1, box2..]

The result would look like this:

The parent element “box1” collapses. The desired target situation would look like this:

01-result-snippet-02

There are many solutions across the web shared by various developers i posted my favorites. The ones, that i perceive most elegant.

Solution 1 – overflow property:

HTML:
<div class="box1 wrapper">
    <ul>
        <li class="float box2">One</li>
        <li class="float box2">Two</li>
        <li class="float box2">Three</li>
    </ul>
</div>

CSS:
.float {
    float: left;
    margin-right: 0.5em;
}

.wrapper {
    overflow: auto;
}

[..and some formatting of ul, box1, box2..]

The first solution proposes the use of the CSS property”overflow” with the value “auto” for the parent element. While this solves our problem instantly, a scroll-bar might occur in some cases, which is not desired in all cases. As this is not the stated purpose of the “overflow” property, this solution seems like a hack.

Check out the Fiddle for Solution 1

Solution 2 – CSS micro clearfix:

HTML:
<div class="box1 clearfix">
    <ul>
        <li class="float box2">One</li>
        <li class="float box2">Two</li>
        <li class="float box2">Three</li>
    </ul>
</div>

CSS:
.float {
    float: left;
    margin-right: 0.5em;
}

.clearfix:before,
.clearfix:after {
  content:"";
  display:table;
}
.clearfix:after {
  clear:both;
}
.clearfix {
  zoom:1; /* For IE 6/7 (trigger hasLayout) */
}

[..and some formatting of ul, box1, box2..]

The second solution proposes the use of a CSS trick. The most recent and globally adopted clearfix solution, the Micro Clearfix by Nicolas Gallagher. Known support for Firefox 3.5+, Safari 4+, Chrome, Opera 9+, IE 6+. Hence, you don’t need to worry about older browsers failing and it does not use the “overflow” property.

Check out the Fiddle for Solution 2

Solution 3 – inner-block:

HTML:
<div class="box1">
    <ul>
        <li class="float box2">One</li>
        <li class="float box2">Two</li>
        <li class="float box2">Three</li>
    </ul>
</div>

CSS:
.float {
    display: inline-block;
    margin-right: 0.5em;
}

[..and some formatting of ul, box1, box2..]

The third solution transforms the block elements into inner-blocks, which emulates the floating without collapsing the parent element. While inline-block used to make problems across different browsers in the past, it is the most flexible solution (as we are going to see below). However, nowadays it seems as inline-blocks are safe to be used in contemporary browsers.

Check out the Fiddle for Solution 3

Solution 4 – extra clearing element:

HTML:
<div class="box1">
    <ul>
        <li class="float box2">One</li>
        <li class="float box2">Two</li>
        <li class="float box2">Three</li>
        <div class="clear"></div>
    </ul>
</div>

CSS:
.float {
    float: left;
    margin-right: 0.5em;    vertical-align: middle;</pre>
<pre>
}

.clear{
 clear:both;
}

[..and some formatting of ul, box1, box2..]

The fourth and last solution presented in this article for the first challenge, uses an extra element within the parent box, which clears the floating to prevent the parent box from collapsing. For dynamic websites an extra element might not always be an option, however an additional css class for the parent box is not necessary.

Check out the Fiddle for Solution 4

Challenge 2: Modify the vertically alignment of floating elements

Having overcome the challenge of floating elements without collapsing the parent element, we consider floating elements of varying sizes.

The problem:

HTML:
<div class="box1 wrapper">
    <ul>
        <li class="float box2" style="height: 30px;">One</li>
        <li class="float box2">Two</li>
        <li class="float box2">Three</li>
    </ul>
</div>

CSS:
.float {
    float: left;
    margin-right: 0.5em;
    vertical-align: middle;
}

.wrapper {
    overflow: auto;
}

[..and some formatting of ul, box1, box2..]

The result would look like this:

Vertical alignment of the elements does not work. The desired target situation would look like this:

We instantly see, that our first solution for Challenge 1 using the “overflow” CSS property, does not allow the use of the “vertical-align” CSS property. The same applies for the proposed solution two and four. Without using any dirty tricks, i can’t think of any solution to vertically aligning floated elements while using the CSS property “float: left”.

Solution using inner-block:

HTML:
<div class="box1">
    <ul>
        <li class="float box2" style="height: 30px;">One</li>
        <li class="float box2">Two</li>
        <li class="float box2">Three</li>
    </ul>
</div>

CSS:
.float {
    display: inline-block;
    margin-right: 0.5em;
    vertical-align: middle;
}

[..and some formatting of ul, box1, box2..]

Vertically alignment works instantly when using the CSS property “display” with inner-block.

Check out the Fiddle for Solution

Challenge 3: Centering floating elements within a parent box

A similar problem occurs, when we aim to center the floated elements within the parent box.

The problem:

HTML:
<div class="box1 wrapper">
    <ul>
        <li class="float box2">One</li>
        <li class="float box2">Two</li>
        <li class="float box2">Three</li>
    </ul>
</div>

CSS:
.float {
    float: left;
    margin-right: 0.5em;
}

.wrapper {
    overflow: auto;
}

ul {
    [..]
    text-align: center;
}

[..and some formatting of ul, box1, box2..]

The result would look like this:

It simply does not work. The desired state is the following:

Similarly to the second challenge, centralizing floated elements is not possible while the CSS property “float” is used to float the elements. You can guess how the solution might look like.

Solution using inner-block:

HTML:
<div class="box1">
    <ul>
        <li class="float box2">One</li>
        <li class="float box2">Two</li>
        <li class="float box2">Three</li>
    </ul>
</div>

CSS:
.float {
    display: inline-block;
    margin-right: 0.5em;
}

ul {
    [..]
    text-align: center;
}

 [..and some formatting of ul, box1, box2..] 

The only solution i came up with, is to again use the “inner-block” for floating the elements.

Check out the Fiddle for Solution

Browser compatibility for the “inner-block” property

As the “inner-block” solution seems to help for all mentioned challenges, we should have a closer look on its browser compatibility.

According to “Caniuse.com”, CSS inline-block is supported fully for all browsers except for Firefox 2, IE 5.5, IE 6 and IE 7.

The CSS property is only supported in IE6 and IE7 on elements with a display of “inline” by default. Alternative properties are available to provide complete cross-browser support. Moreover, the IE 8 has a resize issue with display-inline block.

For more details, please check out the following link.

I would therefore only recommend to use inner-block, if older IEs are not among your target browsers.

Further Reading

Leave a Reply