Overflow:hidden in float. Does it hide anything? - css

I understand that overflow:hidden is a way to clear float, but I do not understand why.
I suppose that If we do use overflow:hidden it is because there is something outside the element that was affected by the float? if so, what is hidden?
For example, in this case, is there anything in #second that is hidden that makes it be beside #first ?
(There is another question that is related, but this is different, this is more specific. My question is: does "overflow:hidden" hide anything? what is it?)
Here is the example: http://jsfiddle.net/NSCpD/
CSS:
#first{
float:left;
width:100px; height:100px;
background:blue;
}
#second{
width:300px; height:300px;
overflow:hidden; /* això fa que no li afecti el float */
background:red;
}
HTML:
<div id="first"> </div>
<div id="second"> </div>

An element with an overflow value other than visible establishes a new Block Formatting Context. The fiddle your provided is a bit different than when an in-flow block level element contains a float. Even if the in-flow block level element is a sibling of an out of flow float it will still acknowledge it's presence as if it were a line box when a new BFC is created. The spec describes this in these two excerpts:
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
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).

As its name suggests, overflow:hidden hides any content that overflows the element (i.e. excesses the given dimensions). In this example there is no overflow actually, so nothing is hidden. But the side-effect of setting the overflow other than visible (as well as display: inline-block, float itself etc.) is the change of the behavior of the block. While the normal block effectively doesn't take floats into account at all (only its text content does), the block that establishes new block formatting context (see Adrift's answer) isolates all of its content inside, including nested floats, potentially collapsible margins etc.
This side effect may be used to prevent the container of floats from collapsing, but it doesn't have anything to do with clearing floats. Clearing and BFCs act very differently in case of collapsible margins, other floats earlier in the document, etc.

Related

How to make container avoid float like its inner text

I feel like there should be an easy answer to this. I have a sidebar floated to the right, when I noticed there were some issues on the hover. Turns out my
<p>
tags on the left were crossing over into the float, even though the text inside them properly avoided the float. I made a simple jsfiddle example to show what I mean, and turned their backgrounds on so you can see them overlapping.
JSFiddle: http://jsfiddle.net/ahvs3nr3/
Adding this CSS fixes the problem:
p {
overflow: auto;
}
Working Fiddle
In your code, the container (p) overflowed the sidebar, even though its content was constrained to not overflow.
From the W3 spec:
Floats, absolutely positioned elements, block containers
... that are not block
boxes, and block boxes with 'overflow' other than 'visible' ... establish new
block formatting contexts for their contents.
This is what led me to try overflow: auto.
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).
This explains why the container overflows the sidebar, but its "line box" (which contains its text) does not.
So what exactly is a "line box"?
In an inline formatting context, boxes are laid out horizontally, one
after the other, beginning at the top of a containing block.
Horizontal margins, borders, and padding are respected between these
boxes. The boxes may be aligned vertically in different ways: their
bottoms or tops may be aligned, or the baselines of text within them
may be aligned. The rectangular area that contains the boxes that form
a line is called a line box. The width of a line box is determined by a
containing block and the presence of floats.
There are no explicit inline elements, so what causes this "inline formatting context"?
Any text that is directly contained inside a block container element
(not inside an inline element) must be treated as an anonymous inline
element.
And there you have it. The text within each paragraph is an "anonymous inline element," which creates a "line box," which is influenced by floats.
I think it's the <p> tag is a block element. Will this work in your case?
p {
display: table;
}
http://jsfiddle.net/ahvs3nr3/3/
Just add some margin right of the p tags.
.sidebar {
background-color:rgba(0,0,0,.2);
float:right;
width:25%;
height:30em;
}
p { background:red; padding:1em; margin-right: 25%; }
I also added a jsfiddle for reference.
http://jsfiddle.net/ahvs3nr3/2/
I use % margins here because they will adapt to any width browser however if you want to use a 5em sidebar just make sure the p tags have the same amount of margin right.

Effect of overflow and clear styles with floats

I'm pretty CSS-savvy, but I'm seeing some odd float/clear behavior. I have it working, but I'm not entirely sure why and am looking for an explanation.
JSFiddle: http://jsfiddle.net/ismyrnow/JV5n6/
I have a 2 column layout - sidebar and content - where the sidebar is floated but the content is not; the content div has a left margin applied to it.
If I use clear:both on any elements in the content div, the element unexpectedly drops below the height of the sidebar div (unexpectedly because the floated sidebar isn't directly affecting the positioning of items inside the content area).
What is even more unexpected, is that when I add overflow:auto to the content div, the problem goes away. (I found the solution here)
Can someone explain:
Why clear:both would cause an element to clear a floated element that isn't directly affecting its position.
Why overflow:auto on the parent element fixes the issue.
Why clear:both would cause an element to clear a floated element that isn't directly affecting its position.
It may not be directly affecting its position, but it would still have affected it anyway, because in the absence of any clearance, floats aren't normally restricted in how they affect the rest of the normal flow layout even once they are taken out of it, not even by different parent elements such as your .b content element with the left margin in this case. The only real restriction is that floating elements may only affect elements that come after them in document tree order, i.e. elements that are following (not preceding) siblings, as well as their descendants.
The content that's just above the element within your content column isn't tall enough to push it beneath the floated element. If you remove that declaration, you would see that both .c elements become positioned next to their respective floats as well.
When you add clear, what happens is that it forces the clearing element to be positioned beneath the float regardless of where it ends up horizontally.
Why overflow:auto on the parent element fixes the issue.
This is because any block boxes with overflow other than visible generate block formatting contexts. A property of a block formatting context is that floating boxes outside it can never interact with any boxes inside it, and vice versa.
Once you cause the content element to establish its own block formatting context, your floating element is no longer able to affect any elements inside the content element (see the section on the float property), and the clearing element inside it is no longer able to clear any floats that are outside the content element (see the clear property).
For clear:both
The clear CSS property specifies whether an element can be next to floating elements that precede it or must be moved down (cleared) below them.
The clear property applies to both floating and non-floating elements.
When applied to non-floating blocks, it moves the border edge of the element down until it is below the margin edge of all relevant floats. This movement (when it happens) causes margin collapsing not to occur.
When applied to floating elements, it moves the margin edge of the element below the margin edge of all relevant floats. This affects the position of later floats, since later floats cannot be positioned higher than earlier ones.
The floats that are relevant to be cleared are the earlier floats within the same block formatting context.
I hope this will clear your doubt.
This is the link from where i found the above info.....
https://developer.mozilla.org/en-US/docs/Web/CSS/clear

Css float drawbacks

Here goes the code:
<style>
.thumbnail
{
float:left;
width:110px;
height:90px;
margin:5px;
}
</style>
<body>
<img src="klematis_small.jpg" style="width:107px; height:140px">
<img class="thumbnail" src="klematis_small.jpg" style="width:107px; height:150px">
The confusing is why the second img which is floated appering before the first img.If we place the first img to second img everything works as expected.
Floated elements are taken out of the normal document flow:
Since a float is not in the flow, non-positioned block boxes created before and after the float box flow vertically as if the float did not exist. However, the current and subsequent line boxes created next to the float are shortened as necessary to make room for the margin box of the float.
Only line boxes (elements in the inline formatting context) respect floats, usually this is in the form of text. Also remember that floats will always be positioned on top (in the stacking order) when colliding with in-flow block level elements, but it will appear behind all lines boxes ..
The contents of floats are stacked as if floats generated new stacking contexts, except that any positioned elements and elements that actually create new stacking contexts take part in the float's parent stacking context. A float can overlap other boxes in the normal flow (e.g., when a normal flow box next to a float has negative margins). When this happens, floats are rendered in front of non-positioned in-flow blocks, but behind in-flow inlines.
The section on floats in the Visual Formatting Model is helpful if you're interested in learning the specifics
References: Section 9.4, Floats, CSS 2.1 Specification
You copy example from W3Schools but didn't read:
How Elements Float
Elements are floated horizontally, this means that an element can only be floated left or right, not up or down.
A floated element will move as far to the left or right as it can.
Usually this means all the way to the left or right of the containing
element.
Yes. This is normal and expected. If you want the first one first, you need to float them both.
I wouldnt use floats, just use display: inline-block; which will display your items exactly in the same order as the code is written.

Why does setting overflow alter layout of child elements?

In this question someone was having a layout problem because they had two floated divs inside a non-floated div. I suggested adding float: left to their outer div, which does fix the problem. Someone else suggested adding overflow: hidden, which to my surprise, also worked.
This doesn't seem at all like the purpose of of overflow: hidden. Clearly overflow: hidden causes elements to view their children differently somehow. What I'm really trying to understand is what that difference is. Intuitively it should only make the element smaller than it would otherwise be, never bigger and I don't see why it would affect the layout hierarchy.
Can anyone explain why this would be correct/necessary behavior or if this is just a browser quirk? Is their another facet to the overflow property I'm missing? Is either solution any better than the other?
Edit: I've discovered setting overflow: auto works too, so it doesn't seem to be the value of overflow that's important, just that it's set. I still don't understand why.
Overflow of anything but visible creates a new block formatting context which causes floats to be contained. It's standard behaviour.
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, boxes
are laid out one after the other,
vertically, beginning at the top of a
containing block. The vertical
distance between two sibling boxes is
determined by the 'margin' properties.
Vertical margins between adjacent
block boxes in a block formatting
context collapse.
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).
Floating items removes them from the normal layout in many cases. It's not exactly like or unlike position: absolute; in that. Block items tend to ignore floated items (including block items that contain the item), but unlike position: absolute; items, floated ones are recognized and wrapped around by inline items, like text.
Having the wrapping item (div or otherwise) also be floated causes it to behave differently related to floated items it contains. Having the wrapping item set to overflow: hidden; forces it to consider the items it contains differently, as well. My guess is it's just a happy coincidence that the end result here appears to be the same. Not a quirk or bug... just how it works out.

side by side divs

I've got 4 divs inside a parent div. To get them to appear side by side, I've given all 4 divs a style with float:left. The divs do appear side by side, but the parent div's height does not grow to encompass the height of the child divs. What am I missing?
This is a quirk cause by the implementation of floating elements, and occurs when you have a parent element that contains nothing but floating child elements. There are two methods to solve it. One is to set the parent element's overflow property to hidden, sometimes known as the overflow method. The other is known as the clearfix method, and involves the use of the :after pseudo-class.
The clearfix method has the advantage of allowing for specifically positioned elements to "hang" outside of the parent container if you ever need them to, at the expense of a bit of extra CSS and markup. This is the method I prefer, as I utilize hanging elements frequently.
Set overflow: hidden; on the parent div.
Explanation: floating elements removes them from the regular document flow. So, if a given element contains only floated elements, it will not have any height (or, by extension, width -- unless it has an implicit width that is default on block elements).
Setting the overflow property to hidden tells the parent element to respect the width of it's children, but hide everything that falls outside it's width and height.
Of course, the other option is to add an element after the floated divs, inside the parent, with clear: both; This makes the last element be positioned after all the floats, within the regular document flow. Since it's inside the parent, the parent's height is whatever the heights of the floated items are, plus regular padding and the height of the cleared item.
After the 4 divs, you need to "cancel" the float style.
This is done through the creation of a p for example, like: <p style="clear: both"></p>
Your parent div will automatically get the right size.
millinet's answer will work, or you could float the parent div which will also allow it to expand to contain its content
I think you should give the parent div a height of 100% not fixed so that it encompasses the height of child divs if they grow.
I recommend the clearfix method as well. This problem occurs because floating an element removes any height that it would normally contain.
PositionIsEverything posts a complete explanation as well as corresponding solutions for IE6, since the :after pseudoselector is not supported by older browsers.
If you want the divs to be side-by-side, you could try using inline-block:
<style>
.alldivs {
display: inline-block;
}
</style>
<div id="wrapper">
<div id="div1" class="alldivs"></div>
<div id="div2" class="alldivs"></div>
<div id="div3" class="alldivs"></div>
<div id="div4" class="alldivs"></div>
</div>

Resources