Dealing with a containing div that contains only floated elements

You have a container with two elements with a class of box floated inside it, both are floated left with a width of 50% of the container. The two elements will sit side by side. However, the containing div may not actually containing the floated elements inside it.

The HTML:

<div class="container">
    <div class="box">
        <h1>Box 1</h1>
        <p>Adipiscing arcu scelerisque massa velit magna auctor urna dictumst diam montes tincidunt diam eu duis! Cum dictumst sed! Nisi in.</p>
    </div>
    <div class="box">
        <h1>Box 2</h1>
        <p>Elit ut dapibus sit sed porta lectus turpis dignissim ridiculus, elit enim urna nascetur pulvinar a penatibus mus? In penatibus.</p>
    </div>
</div>

The CSS:

  .container{
    width: 500px;
    background-color: #fff;
    padding: 10px;
  }

  .box{
    float: left;
    width: 50%;
  }

Floated elements with no border
In demo 1, you can see that the text from both boxes are sitting side by side. But what happens if you add a border and background colour to the container?

  .container{
    width: 500px;
    background-color: #ccc;
    border: 1px #000 solid;
    padding: 10px;
  }

Floated elements, parent has a border

As you can see in demo 2, the background colour and border is not covering the boxes at all. This problem exists because floated (.box) elements are taken out of the flow of the document. Therefore, the container can not determine their height and its own height collapses.

There are various solutions and some involve adding extra divs or a clearfix class. If you want a clean solution without extra divs or classes, there are two good options: float the parent element or add overflow:auto to the parent.

Float parent element

One solution is to float the parent element as well as the child elements. The parent element is the div with the container class so add float:left to it.

  .container{
    width: 500px;
    background-color: #ccc;
    border: 1px #000 solid;
    padding: 10px;
    float: left;
  }

  .box{
    float: left;
    width: 50%;
  }

In demo 3, you can see this working.

Floated elements with floated parent

overflow:auto

In some cases, floating the parent element may cause layout issues. Luckily, there is an alternative, which is to add overflow:auto to the parent element.

  .container{
    width: 500px;
    background-color: #ccc;
    border: 1px #000 solid;
    padding: 10px;
    overflow: auto;
  }

  .box{
    float: left;
    width: 50%;
  }

If you have a good alternative solution, feel free to add it in the comments.

Enjoy this article?

Get my best content on Javascript, CSS, PHP & Git before anyone else and special bonuses.

Get started


Conquer Drupal 8 Module Development

Don't struggle to conquer Drupal 8 module development. Action packed lessons where you will work along building your own real world modules.

20% launch discount available now!

Find out more


Comments

Overflow:auto can result in unhappy things happening if you have links inside, and will not work in older versions of IE. Fortunately overflow:hidden does not have side effects with links, and zoom can trigger hasLayout in IE. So an improved version would be:
.container {
overflow: hidden;
zoom: 1;
}

This will work nicely, and trim off anything that escapes outside of .container.

If you’re using Drupal however, then you’re going to run into trouble trimming off things that overflow, e.g. Contextual Menus. This is probably why Drupal uses the .clearfix class which makes use of the :after hack.

I feel that the Drupal .clearfix unnecessarily impacts performance for my use cases. So I would use:
.container {
_height: 1px; /* IE6 */
min-height: 1px; /* IE7 */
}
.container:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}

Just watch out the the min-height which you may want to override from time to time.

Written as a Less mixin you get:
.fix () {
_height: 1%; /* IE6 */
min-height: 1%; /* IE7 */

&amp;:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
}

Hi Blair, excellent howto with examples, I love the "Float parent element" solution, thanks!

One other solution is to add display: inline-block to the parent. So the css properties for the parent would look like as follows:

.container {
width: 500px;
background-color: #ccc;
border: 1px #000 solid;
padding: 10px;
display: inline-block;
}

Add new comment