27

I read the following code on w3schools and do not understand how the overflow property would impact whether text appears to the right of the ul or not.

ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

li {
  float: left;
}

a {
  display: block;
  width: 60px;
  background-color: #dddddd;
  padding: 8px;
}
<ul>
  <li><a href="#home">Home</a></li>
  <li><a href="#news">News</a></li>
  <li><a href="#contact">Contact</a></li>
  <li><a href="#about">About</a></li>
</ul>
<p><b>Note:</b> overflow:hidden is added to the ul element to prevent li elements from going outside of the list.</p>

I know that overflow:hidden is used to handle content that goes outside of the box but don't understand how it applies in this instance.

Christoph
  • 50,121
  • 21
  • 99
  • 128
Robert
  • 10,126
  • 19
  • 78
  • 130

5 Answers5

47

I try to end the confusion:

ul is a block-level element as is the p element (they stretch to 100% of the parent width). That is why per default the p will appear below the ul if no width or display is declared on those elements.

Now in your example the ul contains only floated elements. This makes it collapse to a height of 0px (It still has 100% width though as you can see in the example). The adjacent p will appear to the right of the floated lis because they are considered as normal floated elements.

Now declaring overflow (any value other than visible) establishes a new block formatting context, which makes the ul contains its children. Suddenly the ul "reappears", not having size 0px anymore. The p is getting pushed to the bottom. You could also declare position:absolute to achieve the same "clearing" effect (with the side effect that now the ul is taken out of the normal element flow - the ps will be overlapped by the ul.)

See the example fiddle

If you are into the technical stuff, compare the according paragraphs of the CSS spec:

§10.6.3 Block-level non-replaced elements in normal flow when 'overflow' computes to 'visible'
and
§10.6.7 'Auto' heights for block formatting context roots. (Thanks to BoltClock for digging out the links).

ul{
    list-style-type:none;
    margin:0; padding:0;
    background-color:#dddddd;
    border:2px solid red;
}
li{
    float:left;
}
a{
    display:block;
    width:60px;
    background-color:#555;
    color:white;
}
p{
    margin:0;
    outline:2px dotted blue;
}
#two{
    clear:both;
    overflow:hidden;
}
No overflow:
<ul>
<li><a href="#home">Home</a></li>
<li><a href="#news">News</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#about">About</a></li>
</ul>
<p>Notice the collapsed ul - no background-color visible, collapsed border and this paragraph treats the lis as regular floats  </p>
<br>
With overflow: hidden
<ul id="two">
<li><a href="#home">Home</a></li>
<li><a href="#news">News</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="#about">About</a></li>
</ul>
<p>the ul reappeared - it now contains the child li's - the float is cleared</p>
Christoph
  • 50,121
  • 21
  • 99
  • 128
  • 12
    +1 finally an even better answer ;) Note that the reason *why* `ul` has zero height when its children are floated is because parent height calculation ignores floats since they're not in normal flow if the parent does not create a BFC for them. Compare [§10.6.3 Block-level non-replaced elements in normal flow when 'overflow' computes to 'visible'](http://www.w3.org/TR/CSS21/visudet.html#normal-block) with [§10.6.7 'Auto' heights for block formatting context roots](http://www.w3.org/TR/CSS21/visudet.html#root-height) – BoltClock Apr 17 '13 at 09:59
  • @BoltClock Excellent, I was looking for these paragraphs. Thanks for sharing! I will add those to the answer. – Christoph Apr 17 '13 at 11:00
13

Setting overflow: hidden on an element causes a new float context to be created, so elements that are floated inside an element that has overflow: hidden applied are cleared.

http://www.w3.org/TR/CSS2/visuren.html#block-formatting

ryanbrill
  • 1,981
  • 10
  • 13
1

To quote from HTML & CSS Is Hard

To summarize, when you have an extra unfloated HTML element at the bottom of a container div, use the clear solution. Otherwise, add an overflow: hidden declaration to the container element. The underlying idea for both options is that you need a way to tell the browser to incorporate floats into the height of their container element

Qiulang
  • 10,295
  • 11
  • 80
  • 129
-1

Instead of the overflow:hidden; use clear:both; for the <p>. here it is in use http://jsfiddle.net/Mvv8w/. Basically overflow:hidden will clear anything that is aside it just as clear:both; does.

Tyler
  • 152
  • 6
  • That's not the same. Take a look at your [modified example](http://jsfiddle.net/Mvv8w/1/) – Christoph Apr 16 '13 at 17:13
  • i didn't say they were the same?. i just said that it will clear elements aside it. So there was no need for the negative rating. – Tyler Apr 17 '13 at 08:25
  • 1) I didn't downvote. 2) As you can see from the fiddle I posted the overflow in this example is used to make the parent element contain the floated child elements. I put background-color on the ul to make it clear: the second ul expands to contain it's floated children while the float in the first list are cleared too, but the ul fails to contain it's floated child li and thus has height 0 = no backgroundcolor. – Christoph Apr 17 '13 at 08:49
-1

This is why w3schools is not a reliable source for web designer/developers. You are correct, it is a terrible example.

It doesn't because, in this example, the parent element does not have a fixed with. Furthermore, it's an un-ordered list tag, which is going to stretch to the size of it's children regardless.

http://jsfiddle.net/EhphH/

CSS

.parent {
    width: 150px;
    height: 100px;
    padding: 10px;
    background: yellow;
    overflow: hidden;

}
.child {
    float: left;
    width: 75px;
    height: 120px;
    margin: 10px;
    background: blue;

}
.baby {
    width: 200px;
    height: 25px;
    background: green;
}

Markup

<div class="parent">
    <div class="child">
        <div class="baby">
        </div>
    </div>
    <div class="child">
    </div>
</div>
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Plummer
  • 6,522
  • 13
  • 47
  • 75
  • 1
    Lighten up before you have a stroke. Angry is no way to live. – Plummer Apr 16 '13 at 20:09
  • Hehe, I'm not angry at all. I'm amused how certain people can be about their wrong opinion. You should take a deeper look at my example fiddle and meditate some hours about it. – Christoph Apr 16 '13 at 23:06
  • @tPlummer: "Lighten up before you have a stroke. Angry is no way to live." [Speak](http://stackoverflow.com/revisions/16041526/1) for [yourself](http://stackoverflow.com/revisions/16041526/2). Anyway, because jsFiddle has been down for me all afternoon, I'm going to assume that what you've added in is fact the same code that's in your link - although given your position on this it still seems a bit dubious. – BoltClock Apr 17 '13 at 09:36
  • @BoltClock: "I read the following code on w3schools and do not see how is it that the overflow property has such an effect as to weather text appears to the right of the "ul" or not."...then..."I know that the overflow:hidden etc. is use to handle content the goes outside of the box but, don't see how this happens in this simple example." I answered the question the OP asked and provided an example.. The resource he was using is known to be unreliable. Everything that came afterwards all extended from my colorful take on Christoph's need to critique beyond what was necessary. Apologies. – Plummer Apr 17 '13 at 14:33