I have a div and an image inside it
<div>
<img src="logo.png">
</div>
img {
float: left;
}
I can see the div have collapsed, the height have become to 0,
my first question is, but the image is inside the, cuz the div's height is 0,why the image still can be see?
I know the solution like give the div a overflow property, even to auto. But why it can solve the problem?
By default, a parent element will not wrap around floated content. (It would be annoying in many situations if it did.) So if you want it to do so, you need to force the container to enclose the floated element. overflow: hidden; is one way of doing it, though it's not always a viable solution. There are quite a few other ways of doing it, too, such as the "clearfix" method.
The overflow property works to contain floats because, to obey the rule, the containing element has to 'look and see' what's inside it. Normally, floated content is taken outside the document flow and mostly ignored by other elements.
Here are some other containment options for that div:
The "clearfix" method:
div:after {
content:"";
display:table;
clear:both;
}
Floating the container:
div.contain {
float: left;
width: 100%;
}
Using display: table:
div {
display: table;
width: 100%;
}
Using display: inline-block:
div {
display: inline-block;
width: 100%;
}
Using position: absolute;:
div {
position: absolute;
width: 100%;
}
Some of these are more useful than others, and context will determine which is and isn't appropriate in any particular layout. Generally, I stick with overflow: hidden unless some content needs to hang out of the containing element (such as in a drop down menu), in which case I'll normally use the "clearfix" option.
Floating elements doesn't affect the size of the parent element. As the div only contains floating elements, there is nothing that gives it height.
By setting the overflow style on the parent element (to anything but visible), you force it to contain its elements, so that they can be scrolled.
By not setting a specific size on the parent element, it will get the size from its children, and you don't get scrollbars. As the children are now contained, the floating elements will affect the size of the parent.
An alternative to using overflow on the parent element, is to add a non-floating child after the other, and use clear: both; on it so that it's below the floating children. That way the parent will contain the children because of that last non-floating child.
Related
In this example...
HTML
<body>
<div>
<div>foo bar</div>
</div>
</body>
CSS
body, html, div {
height: 100%;
margin: 0;
}
div div {
display: inline-block;
overflow: hidden;
}
Why does overflow: hidden cause a vertical scrollbar? Additionally, why is this height not attributed to anything on the page? It's like an invisible margin.
The 100% height of all the elements is intentional. In theory, that should cause the inner-most div to expand to meet the viewport. And it does! ...so long as overflow: hidden is not there, Why?
The extra height is the same height as the height difference between vertical-align: baseline, and vertical-align: bottom. The "descender line". That's where the seemingly random "5 extra pixels" comes from. If the font size is 10 times as large, this gap will also be 10 times as large.
Also, it seems that when overflow: hidden is not there, the inline-block element has its baseline as the same baseline of its last line of text.
This leads me to believe that overflow: hidden forces the baseline of the entire inline-block element to be at the bottom of the element. Even though there is no text there, the parent of the inline-block element reserves space for the descender line. In the example given in the question, it cannot be easily seen since the parent of the inline-block element has height: 100%. So, instead, that extra space reserved for the descender line overflows out of that parent div.
Why is this space still there, even though there's no text? I think that's because the inline-block creates an inline formatting context, which is what causes this space. Were this element to be a block, it would only create this inline formatting context once it encounters an inline element or text.
This is just a theory, but it seems to explain it. It also explains why #Jonny Synthetic's answer works: adding overflow: hidden to the parent hides that extra descender line.
Thanks to #Hashem Qolami for the jsbins that gave me this theory.
Adding overflow: hidden to the parent div wasn't an option for me, and also because of my HTML's structure it wasn't working.
However, I noticed thanks to #Tony Gustafsson's comment in the OP that this does fix the problem:
div div {
vertical-align: bottom;
}
Items with a height of 100% need to have overflow: hidden as well. The first css rule only targets the outside div, the overflow hidden is being applied to the inside div.
Jsfiddle with this CSS and it worked fine:
body, html, div {
height: 100%;
margin: 0px;
padding:0px;
overflow: hidden;
}
div div {
display: inline-block;
overflow: hidden;
}
I am learning how to vertically align element and found one approach(Floater Div) here:
http://www.vanseodesign.com/css/vertical-centering/
**HTML**
<div id="parent">
<div id="floater"></div>
<div id="child">Content here</div>
</div>
**CSS**
#parent {height: 250px;}
#floater {
float: left;
height: 50%;
width: 100%;
margin-bottom: -50px;
}
#child {
clear: both;
height: 100px;
}
Why we need #floater to be floated? Deleting float:left and clear: both still works. What's the benefit of making it floated?
I know there are lots of ways to vertically align element, and seems each of them have some disadvantage like you need to know the height; old IE won't work; multiple lines won't work and so on. But for this approach it put one element to fill up the entire upper half of the parent element. I just wonder why this element need to be floater?
This might not be the best approach to vertically align elements.
For float:left, 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. But in this case since there are no other elements in the document the floater div will start from left even without float:left
The clear property specifies which side(s) of an element other floating elements are not allowed.
clear: both - No floating elements allowed on either the left or the right side
Elements after the floating element will flow around it. To avoid this, we use the clear property.The clear property specifies which sides of an element other floating elements are not allowed.
This makes sure that the child element is not on either left or right of div, but clearing it does not make any changes, you are right, it might though in some cases.
This approach is though very restrictive as you have to know the hieght of child elements and also if there are more elements inside the parent div this will not work.
For much better methods of vertical alignment refer this question
This question is best explained by this fiddle, with the following HTML:
<div class="outer">
<div class="inner-left"></div>
<div class="inner-right"></div>
</div>
CSS:
.outer {
width: 100px;
border: solid 5px #000;
}
.inner-left {
float: left;
height: 200px;
width: 50px;
background: #f00;
}
.inner-right {
float: right;
height: 200px;
width: 50px;
background: #0f0;
}
Basically, I'm wondering why does overflow: hidden cause the outer element to grow in height, encompassing the two floated elements?
To put it most simply, it is because a block box with an overflow that isn't visible (the default) creates a new block formatting context.
Boxes that create new block formatting contexts are defined to stretch to contain their floats by height if they themselves do not have a specified height, defaulting to auto (the spec calls these boxes block formatting context roots):
10.6.7 'Auto' heights for block formatting context roots
In certain cases (see, e.g., sections 10.6.4 and 10.6.6 above), the height of an element that establishes a block formatting context is computed as follows:
[...]
In addition, if the element has any floating descendants whose bottom margin edge is below the element's bottom content edge, then the height is increased to include those edges. Only floats that participate in this block formatting context are taken into account, e.g., floats inside absolutely positioned descendants or other floats are not.
This was not the case in the original CSS2 spec, but was introduced as a change in CSS2.1 in response to a different (and much more pressing) issue. This answer offers an explanation for the changes. For this reason, it seems quite apt to call it a side effect, although the changes were very much intentional.
Also note that this is not the same thing as clearing floats (clearance). Clearance of floats only happens when you use the clear property and there are preceding floats to be cleared:
If you have an element with clear: both that's a sibling of the outer element in your example, the floats will be cleared but the outer element will not stretch.
If you have a similar element (or pseudo-element) as the last child of the outer element instead (making it a following sibling of the floats), the outer element will stretch downward in order to contain the bottom edge of that element, and for a zero-height element that essentially means the bottommost edge of the floats. This technique is known as "clearfix" because the element (or pseudo-element) has no other purpose than to force the outer element to contain the floats by way of clearance within it.
The way I explain it to my students is:
You trigger the element containing the floats by telling it, "everything that is to much, don't show", so the element will look for any content that is too much, and it will find some elements that are floating, now it knows that it should contain them.
Example of the problem at: http://jsfiddle.net/xZmFg/4/
Surely there is a way to get the description to immediately follow the inputs (below, not to the right) and not end up below the menu...
I realise that with 'float' you are breaking out of the flow of the content, but isn't there a way to only apply to the space inside of the parent container?
You can have your description's and form inputs' parent element contain all their floats using overflow: hidden:
.content-box {
overflow: hidden;
}
This way, they won't interfere with the floats on the sidebar elements.
jsFiddle preview
You can float the container around the inputs and your paragraph:
.content {
float: left;
}
And then drop the clear: left; on .description as it doesn't do anything (or leave it in).
http://jsfiddle.net/ambiguous/QdY44/
<style type="text/css">
.a {
border: 1px solid #000;
position: relative;
}
.b {
background: #F93;
position: absolute;
top: 50px;
left: 50px;
}
</style>
<div class="a">
<div class="b">test</div>
</div>
a's height doesn't autoresize with it's content(beause b has flow), but how to resolve this problem, use css possible, not javascript.
If you are expecting to see your a-div resize, then I think you've misunderstood something. When you set an element to be absolute, you're taking it out of the "rendering flow", which means it won't interfere with any other elements on the page.
In the absolute positioning model, a box is explicitly offset with respect to its containing block. It is removed from the normal flow entirely (it has no impact on later siblings). An absolutely positioned box establishes a new containing block for normal flow children and absolutely (but not fixed) positioned descendants. However, the contents of an absolutely positioned element do not flow around any other boxes. They may obscure the contents of another box (or be obscured themselves), depending on the stack levels of the overlapping boxes.
You see the following documentation: Absolute positioning
When you have a Div with position:relative, you can control any absolute element inside. In fact, absolute Div is out of the flow of the normal document as Greg mentioned above. As I see you set left and top for b and then if you set width of a to 60px like this. Your <div class="b"> is outside the parent box. This is how absolute elements work.
Try "float: left;" in both classes. Didn't test, however. In wich browser are you testing?
if div b is positioned absolute it's not considered 'inside a' anymore, because it's not rendered inside of it.
so div a will not resize as div b gets larger or smalller...
By setting position: absolute you're taking the div outside the normal document flow, which is why the container won't resize to contain it.
Did you want to set margin-top: 50px; margin-left: 50px; instead?