How Does CSS 'Overflow:Hidden' Work to Force an Element (Containing Floated Elements) to Wrap Around Floated Elements

How does CSS 'overflow:hidden' work to force an element (containing floated elements) to wrap around floated elements?

Floats, absolutely positioned
elements, inline-blocks, table-cells,
table-captions, and elements with
'overflow' other than 'visible'
(except when that value has been
propagated to the viewport) establish
new block formatting contexts.

In a block formatting context, each
box's left outer edge touches the left
edge of the containing block (for
right-to-left formatting, right edges
touch). This is true even in the
presence of floats (although a box's
line boxes may shrink due to the
floats), unless the box establishes a
new block formatting context (in which
case the box itself may become
narrower due to the floats).

The block formatting context clears the floats. Source: http://www.w3.org/TR/CSS2/visuren.html#block-formatting

Why does overflow hidden stop floating elements escaping their container?

It creates a block formatting context.

Block formatting contexts are important for the positioning (see float) and clearing (see clear) of floats. The rules for positioning
and clearing of floats apply only to things within the same block
formatting context. Floats do not affect the layout of things in other
block formatting contexts, and clear only clears past floats in the
same block formatting context.

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

Floating elements within a div, floats outside of div. Why?

The easiest is to put overflow:hidden on the parent div and don't specify a height:

#parent { overflow: hidden }

Another way is to also float the parent div:

#parent { float: left; width: 100% }

Another way uses a clear element:

<div class="parent">
<img class="floated_child" src="..." />
<span class="clear"></span>
</div>

CSS

span.clear { clear: left; display: block; }

Do clear:both and overflow:hidden work the same way to make a container wrap floated children?

Do clear:both and overflow:hidden work the same way to make a container wrap floated children?

No. They perform different functions.

clear:both

The clear property controls whether an element can be next to or below floated elements that come before it. It controls whether an element can clear the floated elements.

clear:both, when applied to a non-floating, block-level element:

Requires that the top border edge of the box be below the bottom outer edge of any right-floating and left-floating boxes that resulted from elements earlier in the source document.

source: https://www.w3.org/TR/CSS2/visuren.html#propdef-clear

So the clear property more likely applies to a sibling of floated elements. It has nothing to do with stretching the height of div which has float children (as stated in your question).

overflow:hidden (or overflow:auto)

The overflow property, when used with a value other than visible, creates a new block formatting context. This causes the element containing floats to expand in order to contain its floated children.

In summary, one property clears an element past floated elements. The other stretches the container to wrap floated elements. The output may appear the same for both. But each property is fundamentally different.

Further reading:

  • 3. Scrollable Overflow: the overflow-x, overflow-y, and overflow properties
  • What is a clearfix?
  • What methods of ‘clearfix’ can I use?

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 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>

Please explain overflow:hidden 's effect on backgrounds?

It creates a new block formatting context, which clears the floats.

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

And.. it does clip overflowing content: http://jsfiddle.net/rDmhn/

CSS non-wrapping floating divs

Use display: inline-block instead of floatand give the container white-space: nowrap.

div#sub > div#ranking {
position:relative;
top:42px;
left:7px;
width:722px;
height:125px;
overflow-x:auto;
overflow-y:hidden;
white-space: nowrap;
}
div#sub > div#ranking > div.player {
display: inline-block;
width:67px;
height:120px;
margin-left:5px;
background-color:#f3e1bb;
}

Here an example: http://jsfiddle.net/D5hUu/3/

Should we use both overflow: hidden and display:inline?

display: inline is a fix for IE6 to prevent the double-margin bug. If you ever float something, then it's a good idea to include it. If you have an IE-specific stylesheet then it may be best to keep it there (it's a useless property otherwise).

overflow: hidden is a technique used to force an element containing floating elements to take up the full height of the content. Example:

<div class="wrapper">
<div class="floater">floating element</div>
</div>

Here, the height of the wrapper would be 0 since it only contains floating elements. To fix that, you add one of two properties to the wrapper: overflow: hidden or float: left.

Both will force the wrapper to have the correct height, however the float one will obviously float the element too, which you may not want. If the wrapper has a fixed height, then don't use overflow because text may become hidden.

So basically, you don't need overflow: hidden if you already have float: left. But you can keep display: inline for IE6.



Related Topics



Leave a reply



Submit