CSS overflow:hidden with floats
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 li
s 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 p
s 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>
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