What does overflow: hidden do for ul tag?

Zhao Li picture Zhao Li · Oct 20, 2012 · Viewed 23.4k times · Source

I'm creating a multiple column list using the directions from this article:

http://csswizardry.com/2010/02/mutiple-column-lists-using-one-ul/

In a nutshell, it says to do something along the lines of this:

HTML:

<div class='block'>
  <ul>
    <li>
      Item1
    </li>
    <li>
      Item2
    </li>
    <li>
      Item3
    </li>
  </ul>
</div>

CSS:

.block {
    border: 1px solid black;
    padding: 10px;
}
.block ul {
    width: 100%;
    overflow: hidden;
}
.block ul li {
    display: inline;
    float: left;
    width: 50%;
}

And it works wonderfully, but I was mind-boggled at the overflow:hidden CSS declaration.

Without it, my outer div collapses like so:

http://jsfiddle.net/alininja/KQ9Nm/1/

When it's included, the outer div behaves exactly as how I would want it to be:

http://jsfiddle.net/alininja/KQ9Nm/2/

I'm wondering why overflow: hidden is triggering this behaviour. I would expect it to cutoff the inner li items instead of forcing the outer div to expand to the necessary height.

Thank you for looking!

Answer

TheZ picture TheZ · Oct 20, 2012

Anything inside that might be floating does not get clipped unless you have the overflow set to either hidden, scroll or auto. The real magic of the method is that without having given the element a set height, when you set overflow to hidden it takes on the height of the inner elements.

Here the div would not wrap around the img because the img is floating.

<div><img style="float:left;height:100px" /></div>

Here the div will actualize the height of the img now that is has a proper overflow.

<div style="overflow:hidden"><img style="float:left;height:100px" /></div>

If you were to give it a set height and then set overflow hidden it would chop anything that would otherwise have overflowed outwards.

<div style="overflow:hidden;height:50px"><img style="float:left;height:100px" /></div>

Note that in a lot of cases these techniques can be used to avoid clear:both type extra markup.