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
andoverflow: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
, andoverflow
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 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>
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 float
and 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
Stacking Order of Elements Affected by Opacity
How to Make This Header/Content/Footer Layout Using CSS
Vertically Centering Content of :Before/:After Pseudo-Elements
Selenium Webdriver Get Text from CSS Property "Content" on a ::Before Pseudo Element
Are Alternate Nested Styles Possible in CSS
@Media Media Query and ASP.NET MVC Razor Syntax Clash
How to Use Camelcase in CSS Class Names
How to Change CSS Validation Scheme in VS2010
Allowed Characters for CSS Identifiers
CSS Specificity and Inheritance
Changing Chunk Background Color in Rmarkdown
Why Put in Front of the File Name "_" or "_" in SCSS/Css
What's the Difference Between CSS3's :Root Pseudo Class and HTML