I\'m facing problem with floating elements inside div only , here is the problem:
This is the logical behavior of how the elements should be painted but you are having an overflow issue combined with how float works that is making things strange.
Let's remove some properties and follow the code step by step. Let's start by removing overflow:auto
from main
and the fixed height from .second
.main {
border-style: solid;
border-color: yellow;
/* overflow: auto;*/
}
.first {
width: 200px;
height: 100px;
float: left;
border: 10px solid green;
}
.second {
width: 200px;
/*height: 50px;*/
border: 10px solid blue;
}
<div class="main">
<div class="first">test1</div>
<div class="second">test2</div>
</div>
As you can see, the floating element green is above the the blue div and floating only around its content which is text. Like you can read here:
The float CSS property specifies that an element should be placed along the left or right side of its container, allowing text and inline elements to wrap around it. The element is removed from the normal flow of the web page, though still remaining a part of the flow (in contrast to absolute positioning).
And since both div
have the same width the text will be at the bottom and not the right. You can change the width
of the blue div to see the difference:
.main {
border-style: solid;
border-color: yellow;
/* overflow: auto;*/
}
.first {
width: 200px;
height: 100px;
float: left;
border: 10px solid green;
}
.second {
width: 200px;
/*height: 50px;*/
border: 10px solid blue;
animation:change 1s infinite alternate linear;
}
@keyframes change{
from{width:200px}
to{width:400px}
}
<div class="main">
<div class="first">test1</div>
<div class="second">test2</div>
</div>
Now if you check the painting order you will see that we first print the border/background of block non-floating element in the step (4) then we print the floating element in the step (5) then we print the content of the non-floating element in the step (7) which explain why you see the blue under the green
Now if we add a fixed height to the blue element you will face an overflow issue so the content of the blue will stay outside (like in the previous code) BUT the border that define the limit of the element will be behind the green element (like described in the paiting order)
Here is a code with animation to better understand what is happening:
.main {
border-style: solid;
border-color: yellow;
/* overflow: auto;*/
}
.first {
width: 200px;
height: 100px;
float: left;
border: 10px solid green;
}
.second {
width: 200px;
border: 10px solid blue;
animation:change 2s infinite alternate linear;
}
@keyframes change {
from{height:300px;}
to{height:50px;}
}
<div class="main">
<div class="first">test1</div>
<div class="second">test2</div>
</div>
You can also clearly see that the height of main
yellow element is following the height of the blue one because it's the only in-flow element which explain your second question about float not being considered in the height of their parent element BUT by adding overflow:auto
you will create a block formatting context thus the element will behave differently and will consider the height of floating elements inside:
.main {
border-style: solid;
border-color: yellow;
overflow: auto;
}
.first {
width: 200px;
height: 100px;
float: left;
border: 10px solid green;
}
.second {
width: 200px;
border: 10px solid blue;
animation:change 2s infinite alternate linear;
}
@keyframes change {
from{height:300px;}
to{height:50px;}
}
<div class="main">
<div class="first">test1</div>
<div class="second">test2</div>
</div>
In this last you can clearly see the overflow issue that is making the text to be outside the blue div because oveflow:auto
is adding a scroll bar.
When you add a float property to any div, its parent stops taking any heights of the floated property. And anything that you add after the floated div the parent takes its height. If you removed the overflow: auto
, you will see that the parent will take only height of the 2nd non-floated element. Although overflow:auto solves the problem of parent not taking complete height, but it doesn't solve the issue of non-floated element taking space from the start of the parent element (and not after the floated element).
So to fix that, you need to clear the float applied on the first div so that your next div(non-float) come below the floating div and both floating and non-floating divs take the required heights.
Refer this link for more information on float
I usually use the clearfix
class method to solve such an issue.
.clearfix {
content: "";
clear: both;
display: table;
}
.clearfix {
content: "";
clear: both;
display: table;
}
.main {
border-style: solid;
border-color: yellow;
overflow: auto;
}
.first {
width: 200px;
height: 100px;
float: left;
border: 10px solid green;
}
.second {
width: 200px;
height: 50px;
border: 10px solid blue;
}
<div class="main">
<div class="first">test1</div>
<div class="clearfix"></div>
<div class="second">test2</div>
</div>
.clearfix {
content: "";
clear: both;
display: table;
}
.main {
border-style: solid;
border-color: yellow;
overflow: auto;
}
.first {
width: 200px;
height: 100px;
float: left;
border: 10px solid green;
}
.second {
width: 200px;
height: 50px;
border: 20px solid blue;
}
<div class="main">
<div class="first">test1</div>
<div class="second">test2</div>
</div>